Added UX plugin
This commit is contained in:
4
plugins/000_redmine_x_ux_upgrade/Gemfile
Executable file
4
plugins/000_redmine_x_ux_upgrade/Gemfile
Executable file
@@ -0,0 +1,4 @@
|
||||
group :development do
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
end
|
||||
41
plugins/000_redmine_x_ux_upgrade/README.md
Normal file
41
plugins/000_redmine_x_ux_upgrade/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
#RedmineX UX Upgrade Plugin
|
||||
# Foreword
|
||||
============
|
||||
Thank you for purchasing the RedmineX UX Upgrade plugin. Below, you will find useful information about the plugin.
|
||||
|
||||
|
||||
# Contents
|
||||
============
|
||||
1. Installation
|
||||
2. Update
|
||||
|
||||
## 1. Installation of the UX Upgrade Plugin
|
||||
============
|
||||
|
||||
Follow the standard Redmine plugin installation procedure: <br/>
|
||||
<ol type='a'>
|
||||
<li>If you are running Redmine using Bitnami, version 4.2.3-27-r02 and above, you will have to make permission adjustments to two of your folders. Go to `/bitnami/redmine/public` and change the `plugin_assets` folder permissions to 777 by running the following command: `chmod -R 777 plugin_assets`. Then go to `/opt/bitnami/redmine/public ` and change the themes folder permissions to 777 by running the following command: `chmod -R 777 themes `. Now you're all set.</li>
|
||||
<li>Unzip the archive and copy it to `redmine_root/plugins` or copy the archive in the same location and perform the unzip command in cour console.</li>
|
||||
<li>from `redmine_root ` run `bundle install`</li>
|
||||
<li>from `redmine_root ` run `bundle exec rake redmine:plugins:migrate RAILS_ENV=production `</li>
|
||||
<li>restart Redmine</li>
|
||||
</ol>
|
||||
|
||||
## 2. Updating The UX Upgrade Plugin
|
||||
============
|
||||
|
||||
These are the steps needed to update the UX Upgrade plugin: <br/>
|
||||
<ol type='a'>
|
||||
<li>Go to `redmine_root/plugins ` and delete the `000_redmine_x_ux_upgrade` folder</li>
|
||||
<li>Go to `redmine_root/public/plugin_assets ` and delete the `000_redmine_x_ux_upgrade` folder</li>
|
||||
<li>Restart Redmine</li>
|
||||
<li>Copy the new UX Upgrade version into the `redmine_root/plugins ` folder</li>
|
||||
<li>from `redmine_root ` run `bundle install`</li>
|
||||
<li>from `redmine_root ` run `bundle exec rake redmine:plugins:migrate RAILS_ENV=production `</li>
|
||||
<li>Restart Redmine</li>
|
||||
</ol>
|
||||
|
||||
Enjoy!
|
||||
RedmineX Team
|
||||
<br/>
|
||||
[www.redmine-x.com](https://www.redmine-x.com)
|
||||
36
plugins/000_redmine_x_ux_upgrade/README.rdoc
Normal file
36
plugins/000_redmine_x_ux_upgrade/README.rdoc
Normal file
@@ -0,0 +1,36 @@
|
||||
= redminex_ux_upgrade
|
||||
|
||||
#RedmineX UX Upgrade Plugin
|
||||
|
||||
#Foreword
|
||||
Thank you for purchasing the RedmineX UX Upgrade plugin. Below, you will find useful information about the plugin.
|
||||
|
||||
#Contents
|
||||
|
||||
1. Installation
|
||||
2. Update
|
||||
|
||||
0. Bitnami
|
||||
If you are running Redmine using Bitnami, version 4.2.3-27-r02 and above, you will have to make permission adjustments to two of your folders. Go to /bitnami/redmine/public and change the plugin_assets folder permissions to 777 by running the following command: chmod -R 777 plugin_assets. Then go to /opt/bitnami/redmine/public and change the themes folder permissions to 777 by running the following command: chmod -R 777 themes. Now you're all set.
|
||||
|
||||
1. Installation of the UX Upgrade Plugin
|
||||
Follow the standard Redmine plugin installation procedure:
|
||||
|
||||
·Unzip the archive and copy it to redmine_root/plugins or copy the archive in the same location and perform the unzip command in cour console.
|
||||
·from redmine_root run bundle install
|
||||
·from redmine_root run bundle exec rake redmine:plugins:migrate RAILS_ENV=production
|
||||
·restart Redmine
|
||||
|
||||
2. Updating The UX Upgrade Plugin
|
||||
These are the steps needed to update the UX Upgrade plugin:
|
||||
|
||||
·Go to redmine_root/plugins and delete the 000_redmine_x_ux_upgrade folder
|
||||
·Go to redmine_root/public/plugin_assets and delete the 000_redmine_x_ux_upgrade folder
|
||||
·Restart Redmine
|
||||
·Copy the new UX Upgrade version into the redmine_root/plugins folder
|
||||
·from redmine_root run bundle install
|
||||
·from redmine_root run bundle exec rake redmine:plugins:migrate RAILS_ENV=production
|
||||
·Restart Redmine
|
||||
|
||||
Enjoy! RedmineX Team
|
||||
www.redmine-x.com
|
||||
@@ -0,0 +1,20 @@
|
||||
# This file is a part of RedmineX UX Upgrade plugin
|
||||
# for Redmine
|
||||
#
|
||||
# Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
# https://www.redmine-x.com
|
||||
#
|
||||
# Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
# Created by Ondřej Svejkovský
|
||||
|
||||
class RedmineXUxUpgradeController < ApplicationController
|
||||
# Redirects root to My Page or Home Page
|
||||
def root
|
||||
if Setting.plugin_000_redmine_x_ux_upgrade[:redirect_to_my_page]
|
||||
redirect_to controller: 'my', action: 'page'
|
||||
else
|
||||
redirect_to controller: 'welcome', action: 'index'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
44
plugins/000_redmine_x_ux_upgrade/app/models/redmine_x_ux_upgrade_setting.rb
Executable file
44
plugins/000_redmine_x_ux_upgrade/app/models/redmine_x_ux_upgrade_setting.rb
Executable file
@@ -0,0 +1,44 @@
|
||||
# This file is a part of RedmineX UX Upgrade plugin
|
||||
# for Redmine
|
||||
#
|
||||
# Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
# https://www.redmine-x.com
|
||||
#
|
||||
# Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
# Created by Ondřej Svejkovský
|
||||
|
||||
class RedmineXUxUpgradeSetting
|
||||
def self.show_contacts_in_new_entity_menu?
|
||||
settings[:show_contacts_in_new_entity_menu].to_i > 0
|
||||
end
|
||||
|
||||
def self.show_documents_in_new_entity_menu?
|
||||
settings[:show_documents_in_new_entity_menu].to_i > 0
|
||||
end
|
||||
|
||||
def self.show_news_in_new_entity_menu?
|
||||
settings[:show_news_in_new_entity_menu].to_i > 0
|
||||
end
|
||||
|
||||
def self.show_spent_time_in_top_menu?
|
||||
settings[:show_spent_time_in_top_menu]
|
||||
end
|
||||
|
||||
def self.number_of_items_in_project_menu
|
||||
if settings[:number_of_items_in_project_menu].to_i < 1
|
||||
8
|
||||
else
|
||||
settings[:number_of_items_in_project_menu].to_i
|
||||
end
|
||||
end
|
||||
|
||||
def self.remember_collapsed_issues_state?
|
||||
settings[:remember_collapsed_issues_state]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.settings
|
||||
RedmineXUxUpgrade.settings
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= call_hook :view_account_login_top %>
|
||||
|
||||
<div id="login-form">
|
||||
<%# Client custom logo %>
|
||||
<div class="login-logo">
|
||||
<%= image_tag(RedmineXUxUpgrade.logo_url) %>
|
||||
</div>
|
||||
|
||||
<%= 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.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 %>
|
||||
|
||||
<%# Citation after the login form %>
|
||||
<div class="login-quote">
|
||||
Happiness is a direction, not a place...<br/>Sydney J. Harris
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= call_hook :view_account_login_bottom %>
|
||||
|
||||
<% if params[:username].present? %>
|
||||
<%= javascript_tag "$('#password').focus();" %>
|
||||
<% else %>
|
||||
<%= javascript_tag "$('#username').focus();" %>
|
||||
<% end %>
|
||||
19
plugins/000_redmine_x_ux_upgrade/app/views/auth_sources/edit.html.erb
Executable file
19
plugins/000_redmine_x_ux_upgrade/app/views/auth_sources/edit.html.erb
Executable file
@@ -0,0 +1,19 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_auth_source_plural), auth_sources_path], @auth_source.name %>
|
||||
|
||||
<%= labelled_form_for @auth_source, :as => :auth_source, :url => auth_source_path(@auth_source), :html => {:id => 'auth_source_form'} do |f| %>
|
||||
<%= render :partial => auth_source_partial_name(@auth_source), :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
20
plugins/000_redmine_x_ux_upgrade/app/views/auth_sources/new.html.erb
Executable file
20
plugins/000_redmine_x_ux_upgrade/app/views/auth_sources/new.html.erb
Executable file
@@ -0,0 +1,20 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_auth_source_plural), auth_sources_path], "#{l(:label_auth_source_new)} (#{@auth_source.auth_method_name})" %>
|
||||
|
||||
<%= labelled_form_for @auth_source, :as => :auth_source, :url => auth_sources_path, :html => {:id => 'auth_source_form'} do |f| %>
|
||||
<%= hidden_field_tag 'type', @auth_source.type %>
|
||||
<%= render :partial => auth_source_partial_name(@auth_source), :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
</div>
|
||||
<% end %>
|
||||
81
plugins/000_redmine_x_ux_upgrade/app/views/custom_fields/_form.html.erb
Executable file
81
plugins/000_redmine_x_ux_upgrade/app/views/custom_fields/_form.html.erb
Executable file
@@ -0,0 +1,81 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= error_messages_for 'custom_field' %>
|
||||
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<div class="box tabular">
|
||||
<p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %></p>
|
||||
<p><%= f.text_field :name, :size => 50, :required => true %></p>
|
||||
<p><%= f.text_area :description, :rows => 7 %></p>
|
||||
|
||||
<% if @custom_field.format.multiple_supported %>
|
||||
<p>
|
||||
<%= f.check_box :multiple %>
|
||||
<% if !@custom_field.new_record? && @custom_field.multiple %>
|
||||
<em class="info"><%= l(:text_turning_multiple_off) %></em>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= render_custom_field_format_partial f, @custom_field %>
|
||||
|
||||
<%= call_hook(:view_custom_fields_form_upper_box, :custom_field => @custom_field, :form => f) %>
|
||||
</div>
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<% if @custom_field.new_record? %>
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
|
||||
<% else %>
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="splitcontentright">
|
||||
<div class="box tabular">
|
||||
<p><%= f.check_box :is_required %></p>
|
||||
|
||||
<% if %w(UserCustomField).include?(@custom_field.class.name) %>
|
||||
<p><%= f.check_box :visible %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @custom_field.is_a?(UserCustomField) %>
|
||||
<p><%= f.check_box :editable %></p>
|
||||
<% end %>
|
||||
|
||||
<% if %w(IssueCustomField UserCustomField ProjectCustomField VersionCustomField GroupCustomField TimeEntryCustomField).include?(@custom_field.class.name) &&
|
||||
@custom_field.format.is_filter_supported %>
|
||||
<p><%= f.check_box :is_filter %></p>
|
||||
<% end %>
|
||||
|
||||
<% if %w(IssueCustomField ProjectCustomField).include?(@custom_field.class.name) && @custom_field.format.searchable_supported %>
|
||||
<p><%= f.check_box :searchable %></p>
|
||||
<% end %>
|
||||
<%= call_hook(:"view_custom_fields_form_#{@custom_field.type.to_s.underscore}", :custom_field => @custom_field, :form => f) %>
|
||||
</div>
|
||||
|
||||
<% if %w(IssueCustomField TimeEntryCustomField ProjectCustomField VersionCustomField).include?(@custom_field.class.name) %>
|
||||
<%= render :partial => 'visibility_by_role_selector', :locals => { :f => f } %>
|
||||
<% end %>
|
||||
|
||||
<% if @custom_field.is_a?(IssueCustomField) %>
|
||||
<%= render :partial => 'visibility_by_tracker_selector', :locals => { :f => f } %>
|
||||
|
||||
<%= render :partial => 'visibility_by_project_selector', :locals => { :f => f } %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% include_calendar_headers_tags %>
|
||||
@@ -0,0 +1,26 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= custom_field_title @custom_field %>
|
||||
|
||||
<%= form_tag new_custom_field_path, :method => 'get' do %>
|
||||
<div class="box">
|
||||
<p><%= l(:label_custom_field_select_type) %>:</p>
|
||||
<p>
|
||||
<%= select_type_radio_buttons(params[:tab]) %>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:label_next).html_safe + " »".html_safe, :name => nil %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
23
plugins/000_redmine_x_ux_upgrade/app/views/documents/edit.html.erb
Executable file
23
plugins/000_redmine_x_ux_upgrade/app/views/documents/edit.html.erb
Executable file
@@ -0,0 +1,23 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%=l(:label_document)%></h2>
|
||||
|
||||
<%= labelled_form_for @document, :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= link_to l(:label_document_new), new_project_document_path(@project), :class => 'icon icon-add',
|
||||
:onclick => 'showAndScrollTo("add-document", "document_title"); return false;' if User.current.allowed_to?(:add_documents, @project) %>
|
||||
</div>
|
||||
|
||||
<div id="add-document" style="display:none;">
|
||||
<h2><%=l(:label_document_new)%></h2>
|
||||
<%= labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= link_to l(:button_cancel), "#", :onclick => '$("#add-document").hide(); return false;' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h2><%=l(:label_document_plural)%></h2>
|
||||
|
||||
<div id="document-list">
|
||||
<% if @grouped.empty? %><p class="nodata"><%= l(:label_no_data) %></p><% end %>
|
||||
|
||||
<% @grouped.keys.sort.__send__(@sort_by == 'date' ? :reverse_each : :each) do |group| %>
|
||||
<div class="document-group document-group-<%= @sort_by %>">
|
||||
<h3 class="group-name"><%= group %></h3>
|
||||
<%= render :partial => 'documents/document', :collection => @grouped[group] %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<h3><%= l(:label_sort_by, '') %></h3>
|
||||
<ul>
|
||||
<li><%= link_to(l(:field_category), {:sort_by => 'category'},
|
||||
:class => (@sort_by == 'category' ? 'selected' :nil)) %></li>
|
||||
<li><%= link_to(l(:label_date), {:sort_by => 'date'},
|
||||
:class => (@sort_by == 'date' ? 'selected' :nil)) %></li>
|
||||
<li><%= link_to(l(:field_title), {:sort_by => 'title'},
|
||||
:class => (@sort_by == 'title' ? 'selected' :nil)) %></li>
|
||||
<li><%= link_to(l(:field_author), {:sort_by => 'author'},
|
||||
:class => (@sort_by == 'author' ? 'selected' :nil)) %></li>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_document_plural)) -%>
|
||||
22
plugins/000_redmine_x_ux_upgrade/app/views/documents/new.html.erb
Executable file
22
plugins/000_redmine_x_ux_upgrade/app/views/documents/new.html.erb
Executable file
@@ -0,0 +1,22 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%=l(:label_document_new)%></h2>
|
||||
|
||||
<%= labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
36
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/_form.html.erb
Executable file
36
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/_form.html.erb
Executable file
@@ -0,0 +1,36 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= error_messages_for 'enumeration' %>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#enumeration_position_name").select2({
|
||||
minimumResultsForSearch: -1,
|
||||
});
|
||||
$('b[role="presentation"]').hide();
|
||||
});
|
||||
</script>
|
||||
<div class="box tabular">
|
||||
<p><%= f.text_field :name %></p>
|
||||
<p><%= f.check_box :active %></p>
|
||||
<p><%= f.check_box :is_default %></p>
|
||||
<%if @enumeration.type == "IssuePriority"%>
|
||||
<p id="issue-priority-color">
|
||||
<%= f.select :position_name, options_for_select(@enumeration.priority_options, @enumeration.position_name), label: l(:color_label)%>
|
||||
</p>
|
||||
<%end %>
|
||||
<% @enumeration.custom_field_values.each do |value| %>
|
||||
<p><%= custom_field_tag_with_label :enumeration, value %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
<% content_for :header_tags do %>
|
||||
<%= stylesheet_link_tag 'projectino_color_selector', plugin: '000_redmine_x_ux_upgrade' %>
|
||||
<% end %>
|
||||
19
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/edit.html.erb
Executable file
19
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/edit.html.erb
Executable file
@@ -0,0 +1,19 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(@enumeration.option_name), enumerations_path], @enumeration.name %>
|
||||
|
||||
<%= labelled_form_for :enumeration, @enumeration, :url => enumeration_path(@enumeration), :html => {:method => :put, :multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
56
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/index.html.erb
Executable file
56
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/index.html.erb
Executable file
@@ -0,0 +1,56 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%=l(:label_enumerations)%></h2>
|
||||
|
||||
<% Enumeration.get_subclasses.each do |klass| %>
|
||||
<h3><%= l(klass::OptionName) %></h3>
|
||||
|
||||
<% enumerations = klass.shared %>
|
||||
|
||||
<p><%= link_to l(:label_enumeration_new), new_enumeration_path(:type => klass.name), :class => 'icon icon-add' %></p>
|
||||
|
||||
<% if enumerations.any? %>
|
||||
<table class="list enumerations"><thead>
|
||||
<tr>
|
||||
<th><%= l(:field_name) %></th>
|
||||
<th><%= l(:field_is_default) %></th>
|
||||
<th><%= l(:field_active) %></th>
|
||||
<%if klass::OptionName == :enumeration_issue_priorities %>
|
||||
<th><%= l(:color_label) %></th>
|
||||
<% end %>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<% enumerations.each do |enumeration| %>
|
||||
<tr>
|
||||
<td class="name"><%= link_to enumeration, edit_enumeration_path(enumeration) %></td>
|
||||
<td class="tick"><%= checked_image enumeration.is_default? %></td>
|
||||
<td class="tick"><%= checked_image enumeration.active? %></td>
|
||||
<%if klass::OptionName == :enumeration_issue_priorities %>
|
||||
<td class="color"></td>
|
||||
<% end %>
|
||||
<td class="buttons">
|
||||
<%= reorder_handle(enumeration, :url => enumeration_path(enumeration), :param => 'enumeration')%>
|
||||
<%= delete_link enumeration_path(enumeration) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% else %>
|
||||
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_enumerations)) -%>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
$(function() { $("table.enumerations tbody").positionedItems(); });
|
||||
<% end %>
|
||||
20
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/new.html.erb
Executable file
20
plugins/000_redmine_x_ux_upgrade/app/views/enumerations/new.html.erb
Executable file
@@ -0,0 +1,20 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(@enumeration.option_name), enumerations_path], l(:label_enumeration_new) %>
|
||||
|
||||
<%= labelled_form_for :enumeration, @enumeration, :url => enumerations_path, :html => {:multipart => true} do |f| %>
|
||||
<%= f.hidden_field :type %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
</div>
|
||||
<% end %>
|
||||
29
plugins/000_redmine_x_ux_upgrade/app/views/files/new.html.erb
Executable file
29
plugins/000_redmine_x_ux_upgrade/app/views/files/new.html.erb
Executable file
@@ -0,0 +1,29 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%=l(:label_attachment_new)%></h2>
|
||||
|
||||
<%= error_messages_for 'attachment' %>
|
||||
<%= form_tag(project_files_path(@project), :multipart => true, :class => "tabular") do %>
|
||||
<div class="box">
|
||||
|
||||
<% if @versions.any? %>
|
||||
<p><label for="version_id"><%=l(:field_version)%></label>
|
||||
<%= select_tag "version_id", content_tag('option', '') +
|
||||
options_from_collection_for_select(@versions, "id", "name") %></p>
|
||||
<% end %>
|
||||
|
||||
<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_add) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,17 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= labelled_form_for @group, :url => group_path(@group), :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
22
plugins/000_redmine_x_ux_upgrade/app/views/groups/new.html.erb
Executable file
22
plugins/000_redmine_x_ux_upgrade/app/views/groups/new.html.erb
Executable file
@@ -0,0 +1,22 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_group_plural), groups_path], l(:label_group_new) %>
|
||||
|
||||
<%= labelled_form_for @group, :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<%= f.submit l(:button_create) %>
|
||||
<%= f.submit l(:button_create_and_continue), :name => 'continue' %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
21
plugins/000_redmine_x_ux_upgrade/app/views/groups/new_users.html.erb
Executable file
21
plugins/000_redmine_x_ux_upgrade/app/views/groups/new_users.html.erb
Executable file
@@ -0,0 +1,21 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%= l(:label_user_new) %></h2>
|
||||
|
||||
<%= form_for(@group, :url => group_users_path(@group), :method => :post) do |f| %>
|
||||
<%= render :partial => 'new_users_form' %>
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_add) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
@@ -0,0 +1,13 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'groups/new_users_modal') %>');
|
||||
showModal('ajax-modal', '700px');
|
||||
19
plugins/000_redmine_x_ux_upgrade/app/views/issue_statuses/edit.html.erb
Executable file
19
plugins/000_redmine_x_ux_upgrade/app/views/issue_statuses/edit.html.erb
Executable file
@@ -0,0 +1,19 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_issue_status_plural), issue_statuses_path], @issue_status.name %>
|
||||
|
||||
<%= labelled_form_for @issue_status do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
19
plugins/000_redmine_x_ux_upgrade/app/views/issue_statuses/new.html.erb
Executable file
19
plugins/000_redmine_x_ux_upgrade/app/views/issue_statuses/new.html.erb
Executable file
@@ -0,0 +1,19 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_issue_status_plural), issue_statuses_path], l(:label_issue_status_new) %>
|
||||
|
||||
<%= labelled_form_for @issue_status do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
</div>
|
||||
<% end %>
|
||||
37
plugins/000_redmine_x_ux_upgrade/app/views/issues/_action_menu.html.erb
Executable file
37
plugins/000_redmine_x_ux_upgrade/app/views/issues/_action_menu.html.erb
Executable file
@@ -0,0 +1,37 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= link_to l(:button_edit), edit_issue_path(@issue),
|
||||
:onclick => 'showAndScrollTo("update", "issue_notes"); return false;',
|
||||
:class => 'icon icon-edit', :accesskey => accesskey(:edit) if @issue.editable? %>
|
||||
<%= link_to l(:button_log_time), new_issue_time_entry_path(@issue),
|
||||
:class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %>
|
||||
<%= link_to "", "javascript:void(0)", :class => 'far fa fa-ellipsis-v', :id => 'issue-action-dropdown-trigger' %>
|
||||
<ul id="issue-action-dropdown" class="menu-children">
|
||||
<li>
|
||||
<%= watcher_link(@issue, User.current) %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to l(:button_copy), project_copy_issue_path(@project, @issue),
|
||||
:class => 'icon icon-copy' if User.current.allowed_to?(:copy_issues, @project) && Issue.allowed_target_projects.any? %>
|
||||
</li>
|
||||
<li>
|
||||
<%= copy_object_url_link(issue_url(@issue, only_path: false)) %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to l(:button_delete), issue_path(@issue),
|
||||
:data => {:confirm => issues_destroy_confirmation_message(@issue)},
|
||||
:method => :delete, :class => 'icon icon-del' if @issue.deletable? %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
<!-- CHANGE - We don't want to show bottom action edit menu, but we have to keep
|
||||
edit partial below -->
|
||||
<%#= render :partial => 'action_menu' %>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
<% if @issue.editable? %>
|
||||
<div id="update" style="display:none;">
|
||||
<h3><%= l(:button_edit) %></h3>
|
||||
<%= render :partial => 'edit' %>
|
||||
</div>
|
||||
<% end %>
|
||||
120
plugins/000_redmine_x_ux_upgrade/app/views/issues/_attributes.html.erb
Executable file
120
plugins/000_redmine_x_ux_upgrade/app/views/issues/_attributes.html.erb
Executable file
@@ -0,0 +1,120 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= labelled_fields_for :issue, @issue do |f| %>
|
||||
|
||||
<div class="projectino-addtitional-fields-wrap">
|
||||
<a id="projectino-addtitional-fields-trigger" href="javascript:void(0)">
|
||||
<span><%= l(:additional_options) %></span>
|
||||
<i class="fal fa fa-angle-down"></i>
|
||||
</a>
|
||||
|
||||
<div class="projectino-addtitional-fields">
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
|
||||
<!-- CHANGE is_private moved here from _form.html.erb -->
|
||||
<% if @issue.safe_attribute? 'is_private' %>
|
||||
<p id="issue_is_private_wrap">
|
||||
<%= f.check_box :is_private, :no_label => true %><label class="inline" for="issue_is_private" id="issue_is_private_label"><%= l(:field_is_private) %></label>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<!-- CHANGE status_id and priority_id moved to _form.html.erb -->
|
||||
|
||||
<!-- CHANGE assigned_to_id and start_date moved to _form.html.erb -->
|
||||
|
||||
<!-- CHANGE category_id a fixed_version_id moved to splitcontentright below -->
|
||||
|
||||
<!-- CHANGE parent_issue_id and done_ration moved here from splitcontentright below -->
|
||||
|
||||
<% if @issue.safe_attribute? 'parent_issue_id' %>
|
||||
<p id="parent_issue"><%= f.text_field :parent_issue_id, :size => 10,
|
||||
:required => @issue.required_attribute?('parent_issue_id'),
|
||||
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %></p>
|
||||
<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript(auto_complete_issues_path(:project_id => @issue.project, :scope => Setting.cross_project_subtasks, :status => @issue.closed? ? 'c' : 'o', :issue_id => @issue.id))}')" %>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute?('done_ratio') && Issue.use_field_for_done_ratio? %>
|
||||
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :required => @issue.required_attribute?('done_ratio') %></p>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="splitcontentright">
|
||||
<!-- CHANGE parent_issue_id, start_date and done_ration moved to splitcontentleft above -->
|
||||
|
||||
<!-- CHANGE due date and estimated hours moved to _form.html.erb -->
|
||||
|
||||
<!-- CHANGE category_id a fixed_Version_id moved here from splitcontentleft above -->
|
||||
|
||||
<% if @issue.safe_attribute?('category_id') && @issue.project.issue_categories.any? %>
|
||||
<p><%= f.select :category_id, (@issue.project.issue_categories.collect {|c| [c.name, c.id]}),
|
||||
{:include_blank => true, :required => @issue.required_attribute?('category_id')},
|
||||
:onchange => ("updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" if @issue.new_record?) %>
|
||||
<%= link_to(l(:label_issue_category_new),
|
||||
new_project_issue_category_path(@issue.project),
|
||||
:remote => true,
|
||||
:method => 'get',
|
||||
:title => l(:label_issue_category_new),
|
||||
:tabindex => 200,
|
||||
:class => 'icon-only icon-add'
|
||||
) if User.current.allowed_to?(:manage_categories, @issue.project) %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute?('fixed_version_id') && @issue.assignable_versions.any? %>
|
||||
<p><%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version),
|
||||
:include_blank => true, :required => @issue.required_attribute?('fixed_version_id') %>
|
||||
<%= link_to(l(:label_version_new),
|
||||
new_project_version_path(@issue.project),
|
||||
:remote => true,
|
||||
:method => 'get',
|
||||
:title => l(:label_version_new),
|
||||
:tabindex => 200,
|
||||
:class => 'icon-only icon-add'
|
||||
) if User.current.allowed_to?(:manage_versions, @issue.project) %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<% if @issue.safe_attribute? 'custom_field_values' %>
|
||||
<%= render :partial => 'issues/form_custom_fields' %>
|
||||
<% end %>
|
||||
|
||||
<!-- CHANGE call_hook :view_issues_form_details_bottom moved here from _form.html.erb -->
|
||||
<%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %>
|
||||
|
||||
<!-- CHANGE watchers_form_container moved here from _new.html.erb -->
|
||||
<!-- Only for new issues -->
|
||||
<% unless @issue.id %>
|
||||
<div id="watchers_form_container">
|
||||
<%= render :partial => 'issues/watchers_form' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% include_calendar_headers_tags %>
|
||||
|
||||
<script>
|
||||
// Activate hiding or opening of additional fields section
|
||||
if (window.RXU) {
|
||||
window.RXU.Issues.hideAddtitionalFields();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", () => window.RXU.Issues.hideAddtitionalFields());
|
||||
}
|
||||
</script>
|
||||
100
plugins/000_redmine_x_ux_upgrade/app/views/issues/_edit.html.erb
Executable file
100
plugins/000_redmine_x_ux_upgrade/app/views/issues/_edit.html.erb
Executable file
@@ -0,0 +1,100 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= labelled_form_for @issue, :html => {:id => 'issue-form', :multipart => true} do |f| %>
|
||||
<%= error_messages_for 'issue', 'time_entry' %>
|
||||
<%= render :partial => 'conflict' if @conflict %>
|
||||
<div class="box">
|
||||
<% if @issue.attributes_editable? %>
|
||||
<fieldset class="tabular"><legend><%= l(:label_change_properties) %></legend>
|
||||
<div id="all_attributes">
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
<% if User.current.allowed_to?(:log_time, @project) %>
|
||||
<fieldset class="tabular"><legend><%= l(:button_log_time) %></legend>
|
||||
<%= labelled_fields_for :time_entry, @time_entry do |time_entry| %>
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<p><%= time_entry.hours_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %></p>
|
||||
</div>
|
||||
<div class="splitcontentright">
|
||||
<p><%= time_entry.select :activity_id, activity_collection_for_select_options %></p>
|
||||
</div>
|
||||
</div>
|
||||
<p><%= time_entry.text_field :comments, :size => 60 %></p>
|
||||
<% @time_entry.editable_custom_field_values.each do |value| %>
|
||||
<p><%= custom_field_tag_with_label :time_entry, value %></p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
<% if @issue.notes_addable? %>
|
||||
<fieldset><legend><%= l(:field_notes) %></legend>
|
||||
<%= f.text_area :notes, :cols => 60, :rows => 10, :class => 'wiki-edit',
|
||||
:data => {
|
||||
:auto_complete => true
|
||||
},
|
||||
:no_label => true %>
|
||||
<%= wikitoolbar_for 'issue_notes', preview_issue_path(:project_id => @project, :issue_id => @issue) %>
|
||||
|
||||
<% if @issue.safe_attribute? 'private_notes' %>
|
||||
<%= f.check_box :private_notes, :no_label => true %> <label for="issue_private_notes"><%= l(:field_private_notes) %></label>
|
||||
<% end %>
|
||||
|
||||
<%= call_hook(:view_issues_edit_notes_bottom, { :issue => @issue, :notes => @notes, :form => f }) %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="files">
|
||||
<legend><%= l(:label_attachment_plural) %></legend>
|
||||
|
||||
<% if @issue.attachments.any? && @issue.safe_attribute?('deleted_attachment_ids') %>
|
||||
<div class="contextual"><%= link_to l(:label_edit_attachments), '#', :onclick => "$('#existing-attachments').toggle(); return false;", :class => "icon-only icon-edit" %></div>
|
||||
<div id="existing-attachments" style="<%= @issue.deleted_attachment_ids.blank? ? 'display:none;' : '' %>">
|
||||
<% @issue.attachments.each do |attachment| %>
|
||||
<span class="existing-attachment">
|
||||
<%= text_field_tag '', attachment.filename, :class => "icon icon-attachment filename", :disabled => true %>
|
||||
<label>
|
||||
<%= check_box_tag 'issue[deleted_attachment_ids][]',
|
||||
attachment.id,
|
||||
@issue.deleted_attachment_ids.include?(attachment.id),
|
||||
:id => nil, :class => "deleted_attachment" %> <%= l(:button_delete) %>
|
||||
</label>
|
||||
</span>
|
||||
<% end %>
|
||||
<hr />
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="new-attachments" style="display:inline-block;">
|
||||
<%= render :partial => 'attachments/form', :locals => {:container => @issue} %>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= f.hidden_field :lock_version %>
|
||||
<%= hidden_field_tag 'last_journal_id', params[:last_journal_id] || @issue.last_journal_id %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_submit) %>
|
||||
<%= link_to(
|
||||
l(:button_cancel), issue_path(id: @issue.id),
|
||||
:onclick => params[:action] == 'show' ? "$('#update').hide(); return false;" : ''
|
||||
) %>
|
||||
</div>
|
||||
<%= hidden_field_tag 'prev_issue_id', @prev_issue_id if @prev_issue_id %>
|
||||
<%= hidden_field_tag 'next_issue_id', @next_issue_id if @next_issue_id %>
|
||||
<%= hidden_field_tag 'issue_position', @issue_position if @issue_position %>
|
||||
<%= hidden_field_tag 'issue_count', @issue_count if @issue_count %>
|
||||
<% end %>
|
||||
182
plugins/000_redmine_x_ux_upgrade/app/views/issues/_form.html.erb
Executable file
182
plugins/000_redmine_x_ux_upgrade/app/views/issues/_form.html.erb
Executable file
@@ -0,0 +1,182 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= labelled_fields_for :issue, @issue do |f| %>
|
||||
<%= call_hook(:view_issues_form_details_top, { :issue => @issue, :form => f }) %>
|
||||
<%= hidden_field_tag 'form_update_triggered_by', '' %>
|
||||
<%= hidden_field_tag 'back_url', params[:back_url], :id => nil if params[:back_url].present? %>
|
||||
|
||||
<!-- CHANGE splitcontent divs added -->
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<!-- CHANGE order of items changed according to projectino plugin -->
|
||||
<% if @issue.safe_attribute? 'subject' %>
|
||||
<p><%= f.text_field :subject, :size => 80, :maxlength => 255, :required => true %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %>
|
||||
<p>
|
||||
<%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
|
||||
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %>
|
||||
<% if @issue.transition_warning %>
|
||||
<span class="icon-only icon-warning" title="<%= @issue.transition_warning %>"><%= @issue.transition_warning %></span>
|
||||
<% end %>
|
||||
</p>
|
||||
<%= hidden_field_tag 'was_default_status', @issue.status_id, :id => nil if @issue.status == @issue.default_status %>
|
||||
<% else %>
|
||||
<p><label><%= l(:field_status) %></label> <%= @issue.status %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute? 'priority_id' %>
|
||||
<p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), {:required => true} %></p>
|
||||
<% end %>
|
||||
|
||||
<!-- CHANGE assigned_to_id moved here from _attributes.html.erb -->
|
||||
<% if @issue.safe_attribute? 'assigned_to_id' %>
|
||||
<p>
|
||||
<%= f.select :assigned_to_id, principals_options_for_select(@issue.assignable_users, @issue.assigned_to),
|
||||
:include_blank => true, :required => @issue.required_attribute?('assigned_to_id') %>
|
||||
<% if @issue.assignable_users.include?(User.current) %>
|
||||
<a class="assign-to-me-link<%= ' hidden' if @issue.assigned_to_id == User.current.id %>" href="#" data-id="<%= User.current.id %>"><%= l(:label_assign_to_me) %></a>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<!-- CHANGE is_private moved to _attributes.html.erb -->
|
||||
</div>
|
||||
<!-- splitcontentright div added to include some items from _attributes.html.erb -->
|
||||
<div class="splitcontentright">
|
||||
|
||||
<!-- CHANGE Project drop down is now always visible, is user is in the project, this project is preselected -->
|
||||
<% projects = projects_for_select(@issue) %>
|
||||
<% if (@issue.safe_attribute?('project_id') || @issue.project_id_changed?) #&& (@project.nil? || projects.length > 1 || @issue.copy?) %>
|
||||
<p><%= f.select :project_id, project_tree_options_for_select(projects, :selected => @issue.project), {:required => true},
|
||||
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute?('tracker_id') || (@issue.persisted? && @issue.tracker_id_changed?) %>
|
||||
<p>
|
||||
<%= f.select :tracker_id, trackers_options_for_select(@issue), {:required => true},
|
||||
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)",
|
||||
:title => @issue.tracker.description %>
|
||||
<%= content_tag 'a', l(:label_open_trackers_description), :class => 'icon-only icon-help', :title => l(:label_open_trackers_description), :onclick => "showModal('trackers_description', '500px'); return false;", :href => '#' if trackers_for_select(@issue).any? {|t| t.description.present? } %>
|
||||
</p>
|
||||
<%= render partial: 'issues/trackers_description', locals: {trackers: trackers_for_select(@issue)} %>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute? 'start_date' %>
|
||||
<p id="start_date_area">
|
||||
<%= f.date_field(:start_date, :size => 10, :required => @issue.required_attribute?('start_date')) %>
|
||||
<%= calendar_for('issue_start_date') %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute? 'due_date' %>
|
||||
<p id="due_date_area">
|
||||
<%= f.date_field(:due_date, :size => 10, :required => @issue.required_attribute?('due_date')) %>
|
||||
<%= calendar_for('issue_due_date') %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute? 'estimated_hours' %>
|
||||
<p><%= f.hours_field :estimated_hours, :size => 3, :required => @issue.required_attribute?('estimated_hours') %> <%= l(:field_hours) %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% @issue_description_edit_id = @issue.safe_attribute?('project_id') && @issue.safe_attribute?('tracker_id') &&
|
||||
@issue.safe_attribute?('start_date') && @issue.safe_attribute?('due_date') &&
|
||||
@issue.safe_attribute?('estimated_hours') && (not @issue.new_record?)
|
||||
%>
|
||||
<% if @issue.safe_attribute? 'description' %>
|
||||
<%= content_tag :p, id: (@issue_description_edit_id ? 'issue_description_edit' : nil) do %>
|
||||
<%= f.label_for_field :description, :required => @issue.required_attribute?('description') %>
|
||||
<%= link_to_function content_tag(:span, l(:button_edit), :class => 'icon icon-edit'), '$(this).hide(); $("#issue_description_and_toolbar").show()' unless @issue.new_record? %>
|
||||
<%= content_tag 'span', :id => "issue_description_and_toolbar", :style => (@issue.new_record? ? nil : 'display:none') do %>
|
||||
<%= f.text_area :description, :cols => 60, :accesskey => accesskey(:edit), :class => 'wiki-edit',
|
||||
:rows => [[10, @issue.description.to_s.length / 50].max, 20].min,
|
||||
:data => {
|
||||
:auto_complete => true
|
||||
},
|
||||
:no_label => true %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= wikitoolbar_for 'issue_description', preview_issue_path(:project_id => @issue.project, :issue_id => @issue.id) %>
|
||||
<% end %>
|
||||
|
||||
<!-- CHANGE attachment is moved here from new.html.erb -->
|
||||
<!-- Only for new issues -->
|
||||
<% unless @issue.id %>
|
||||
<fieldset class="files">
|
||||
<legend><%= l(:label_attachment_plural) %></legend>
|
||||
|
||||
<% if @issue.attachments.any? && @issue.safe_attribute?('deleted_attachment_ids') %>
|
||||
<div class="contextual"><%= link_to l(:label_edit_attachments), '#', :onclick => "$('#existing-attachments').toggle(); return false;", :class => "icon-only icon-edit" %></div>
|
||||
<div id="existing-attachments" style="<%= @issue.deleted_attachment_ids.blank? ? 'display:none;' : '' %>">
|
||||
<% @issue.attachments.each do |attachment| %>
|
||||
<span class="existing-attachment">
|
||||
<%= text_field_tag '', attachment.filename, :class => "icon icon-attachment filename", :disabled => true %>
|
||||
<label>
|
||||
<%= check_box_tag 'issue[deleted_attachment_ids][]',
|
||||
attachment.id,
|
||||
@issue.deleted_attachment_ids.include?(attachment.id),
|
||||
:id => nil, :class => "deleted_attachment" %> <%= l(:button_delete) %>
|
||||
</label>
|
||||
</span>
|
||||
<% end %>
|
||||
<hr />
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="new-attachments" style="display:inline-block;">
|
||||
<%= render :partial => 'attachments/form', :locals => {:container => @issue} %>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
<div id="attributes" class="attributes">
|
||||
<%= render :partial => 'issues/attributes' %>
|
||||
</div>
|
||||
|
||||
<!-- call_hook :view_issues_form_details_bottom moved to _attributes.html.erb -->
|
||||
<% end %>
|
||||
|
||||
<% heads_for_wiki_formatter %>
|
||||
<%= heads_for_auto_complete(@issue.project) %>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
$(document).ready(function(){
|
||||
$("#issue_tracker_id, #issue_status_id").each(function(){
|
||||
$(this).val($(this).find("option[selected=selected]").val());
|
||||
});
|
||||
$(".assign-to-me-link").click(function(event){
|
||||
event.preventDefault();
|
||||
var element = $(event.target);
|
||||
$('#issue_assigned_to_id').val(element.data('id'));
|
||||
element.hide();
|
||||
});
|
||||
$('#issue_assigned_to_id').change(function(event){
|
||||
var assign_to_me_link = $(".assign-to-me-link");
|
||||
|
||||
if (assign_to_me_link.length > 0) {
|
||||
var user_id = $(event.target).val();
|
||||
var current_user_id = assign_to_me_link.data('id');
|
||||
|
||||
if (user_id == current_user_id) {
|
||||
assign_to_me_link.hide();
|
||||
} else {
|
||||
assign_to_me_link.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
<% end %>
|
||||
74
plugins/000_redmine_x_ux_upgrade/app/views/issues/_list.html.erb
Executable file
74
plugins/000_redmine_x_ux_upgrade/app/views/issues/_list.html.erb
Executable file
@@ -0,0 +1,74 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<% query_options = nil unless defined?(query_options) %>
|
||||
<% query_options ||= {} %>
|
||||
|
||||
<%= form_tag({}, :data => {:cm_url => issues_context_menu_path}) do -%>
|
||||
<%= hidden_field_tag 'back_url', url_for(:params => request.query_parameters), :id => nil %>
|
||||
<%= query_columns_hidden_tags(query) %>
|
||||
<div class="autoscroll">
|
||||
<table class="list issues odd-even <%= query.css_classes %>">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="checkbox hide-when-print">
|
||||
<%= check_box_tag 'check_all', '', false, :class => 'toggle-selection',
|
||||
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
|
||||
</th>
|
||||
<% query.inline_columns.each do |column| %>
|
||||
<%= column_header(query, column, query_options) %>
|
||||
<% end %>
|
||||
<th class="buttons"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<script>
|
||||
window.rememberCollapsedIssuesState = <%= Setting.plugin_000_redmine_x_ux_upgrade[:remember_collapsed_issues_state] ? true : false %>;
|
||||
</script>
|
||||
<%# We use group object_id to identify every type of group %>
|
||||
<% grouped_issue_list_projectino(issues, query) do |issue, level, group_name, group_count, group_totals, group_object_id| -%>
|
||||
<% if group_name %>
|
||||
<% reset_cycle %>
|
||||
<tr class="group open">
|
||||
<td colspan="<%= query.inline_columns.size + 2 %>">
|
||||
<%# Toggle functions are replaced by projectino versions, which enable to save state of the boxes
|
||||
- see standard_theme.js %>
|
||||
<span class="expander icon icon-expended issue-group" id="<%= group_object_id %>" data-user="<%= User.current.id %>" onclick="window.RXU.Issues.toggleRowGroupProjectino(this);"> </span>
|
||||
<span class="name"><%= group_name %></span> <span class="badge badge-count count"><%= group_count %></span> <span class="totals"><%= group_totals %></span>
|
||||
<%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
|
||||
"window.RXU.Issues.toggleAllRowGroupsProjectino(this)", :class => 'toggle-all', :'data-user' => User.current.id) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
|
||||
<td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
|
||||
<% query.inline_columns.each do |column| %>
|
||||
<%= content_tag('td', column_content(column, issue), :class => column.css_classes ) %>
|
||||
<% end %>
|
||||
<td class="buttons"><%= link_to_context_menu_with_edit(issue) %></td>
|
||||
</tr>
|
||||
<% query.block_columns.each do |column|
|
||||
if (text = column_content(column, issue)) && text.present? -%>
|
||||
<tr class="<%= current_cycle %>">
|
||||
<td colspan="<%= query.inline_columns.size + 2 %>" class="<%= column.css_classes %> block_column">
|
||||
<% if query.block_columns.count > 1 %>
|
||||
<span><%= column.caption %></span>
|
||||
<% end %>
|
||||
<%= text %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<% end -%>
|
||||
23
plugins/000_redmine_x_ux_upgrade/app/views/issues/_watchers.html.erb
Executable file
23
plugins/000_redmine_x_ux_upgrade/app/views/issues/_watchers.html.erb
Executable file
@@ -0,0 +1,23 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<% if User.current.allowed_to?(:add_issue_watchers, watched.project) %>
|
||||
<div class="contextual">
|
||||
<%= link_to l(:button_add),
|
||||
new_watchers_path(:object_type => watched.class.name.underscore, :object_id => watched),
|
||||
:remote => true,
|
||||
:method => 'get' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<p><strong><%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>)</strong></p>
|
||||
|
||||
<%= watchers_list(watched) %>
|
||||
59
plugins/000_redmine_x_ux_upgrade/app/views/issues/new.html.erb
Executable file
59
plugins/000_redmine_x_ux_upgrade/app/views/issues/new.html.erb
Executable file
@@ -0,0 +1,59 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title l(:label_issue_new) %>
|
||||
|
||||
<%= call_hook(:view_issues_new_top, {:issue => @issue}) %>
|
||||
|
||||
<%= labelled_form_for @issue, :url => _project_issues_path(@project),
|
||||
:html => {:id => 'issue-form', :multipart => true} do |f| %>
|
||||
<%= error_messages_for 'issue' %>
|
||||
<%= hidden_field_tag 'copy_from', params[:copy_from] if params[:copy_from] %>
|
||||
<div class="box tabular">
|
||||
<div id="all_attributes">
|
||||
<%= render :partial => 'issues/form', :locals => {:f => f} %>
|
||||
</div>
|
||||
|
||||
<% if @copy_from && Setting.link_copied_issue == 'ask' %>
|
||||
<p>
|
||||
<label for="link_copy"><%= l(:label_link_copied_issue) %></label>
|
||||
<%= check_box_tag 'link_copy', '1', @link_copy %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if @copy_from && @copy_from.attachments.any? %>
|
||||
<p>
|
||||
<label for="copy_attachments"><%= l(:label_copy_attachments) %></label>
|
||||
<%= check_box_tag 'copy_attachments', '1', @copy_attachments %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if @copy_from && !@copy_from.leaf? %>
|
||||
<p>
|
||||
<label for="copy_subtasks"><%= l(:label_copy_subtasks) %></label>
|
||||
<%= check_box_tag 'copy_subtasks', '1', @copy_subtasks %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<!-- CHANGE attachment form moved to _form.html.erb -->
|
||||
|
||||
<!-- CHANGE watchers_form_container moved to _attributes.html.erb -->
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<% if params[:back_url] && params[:issue] && params[:issue][:parent_issue_id] %>
|
||||
<%= submit_tag l(:button_create_and_follow), name: 'follow' %>
|
||||
<% end %>
|
||||
<%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= robot_exclusion_tag %>
|
||||
<% end %>
|
||||
21
plugins/000_redmine_x_ux_upgrade/app/views/issues/new.js.erb
Normal file
21
plugins/000_redmine_x_ux_upgrade/app/views/issues/new.js.erb
Normal file
@@ -0,0 +1,21 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
replaceIssueFormWith('<%= escape_javascript(render :partial => 'form') %>');
|
||||
<% case params[:form_update_triggered_by] %>
|
||||
<% when "issue_project_id" %>
|
||||
$("#watchers_form_container").html(
|
||||
'<%= escape_javascript(render :partial => 'issues/watchers_form') %>');
|
||||
<% when "issue_category_id" %>
|
||||
$('#issue_assigned_to_id').find('option').first().html(
|
||||
'<%= escape_javascript(
|
||||
@issue.category.try(:assigned_to).try(:name)).presence || ' '.html_safe %>');
|
||||
<% end %>
|
||||
165
plugins/000_redmine_x_ux_upgrade/app/views/issues/show.html.erb
Executable file
165
plugins/000_redmine_x_ux_upgrade/app/views/issues/show.html.erb
Executable file
@@ -0,0 +1,165 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= render :partial => 'action_menu' %>
|
||||
|
||||
<h2 class="inline-flex"><%= issue_heading(@issue) %></h2>
|
||||
<%= issue_status_type_badge(@issue.status) %>
|
||||
<% if @issue.is_private? %>
|
||||
<span class="badge badge-private private"><%= l(:field_is_private) %></span>
|
||||
<% end %>
|
||||
|
||||
<div class="<%= @issue.css_classes %> details">
|
||||
<% if @prev_issue_id || @next_issue_id %>
|
||||
<div class="next-prev-links contextual">
|
||||
<%= link_to_if @prev_issue_id,
|
||||
"\xc2\xab #{l(:label_previous)}",
|
||||
(@prev_issue_id ? issue_path(@prev_issue_id) : nil),
|
||||
:title => "##{@prev_issue_id}",
|
||||
:accesskey => accesskey(:previous) %> |
|
||||
<% if @issue_position && @issue_count %>
|
||||
<span class="position">
|
||||
<%= link_to_if @query_path,
|
||||
l(:label_item_position, :position => @issue_position, :count => @issue_count),
|
||||
@query_path %>
|
||||
</span> |
|
||||
<% end %>
|
||||
<%= link_to_if @next_issue_id,
|
||||
"#{l(:label_next)} \xc2\xbb",
|
||||
(@next_issue_id ? issue_path(@next_issue_id) : nil),
|
||||
:title => "##{@next_issue_id}",
|
||||
:accesskey => accesskey(:next) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="gravatar-with-child">
|
||||
<%= author_avatar(@issue.author, :size => "50") %>
|
||||
<%= assignee_avatar(@issue.assigned_to, :size => "22", :class => "gravatar-child") if @issue.assigned_to %>
|
||||
</div>
|
||||
|
||||
<div class="subject">
|
||||
<%= render_issue_subject_with_tree(@issue) %>
|
||||
</div>
|
||||
<p class="author">
|
||||
<%= authoring @issue.created_on, @issue.author %>.
|
||||
<% if @issue.created_on != @issue.updated_on %>
|
||||
<%= l(:label_updated_time, time_tag(@issue.updated_on)).html_safe %>.
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<div class="attributes">
|
||||
<%= issue_fields_rows do |rows|
|
||||
rows.left l(:field_status), @issue.status.name, :class => 'status'
|
||||
rows.left l(:field_priority), @issue.priority.name, :class => 'priority'
|
||||
rows.left l(:field_author), @issue.author, :class => 'author'
|
||||
unless @issue.disabled_core_fields.include?('assigned_to_id')
|
||||
rows.left l(:field_assigned_to), (@issue.assigned_to ? link_to_principal(@issue.assigned_to) : "-"), :class => 'assigned-to'
|
||||
end
|
||||
unless @issue.disabled_core_fields.include?('category_id') || (@issue.category.nil? && @issue.project.issue_categories.none?)
|
||||
rows.left l(:field_category), (@issue.category ? @issue.category.name : "-"), :class => 'category'
|
||||
end
|
||||
unless @issue.disabled_core_fields.include?('fixed_version_id') || (@issue.fixed_version.nil? && @issue.assignable_versions.none?)
|
||||
rows.left l(:field_fixed_version), (@issue.fixed_version ? link_to_version(@issue.fixed_version) : "-"), :class => 'fixed-version'
|
||||
end
|
||||
|
||||
unless @issue.disabled_core_fields.include?('start_date')
|
||||
rows.right l(:field_start_date), format_date(@issue.start_date), :class => 'start-date'
|
||||
end
|
||||
unless @issue.disabled_core_fields.include?('due_date')
|
||||
rows.right l(:field_due_date), issue_due_date_details(@issue), :class => 'due-date'
|
||||
end
|
||||
unless @issue.disabled_core_fields.include?('done_ratio')
|
||||
rows.right l(:field_done_ratio), progress_bar(@issue.done_ratio, :legend => "#{@issue.done_ratio}%"), :class => 'progress'
|
||||
end
|
||||
unless @issue.disabled_core_fields.include?('estimated_hours')
|
||||
rows.right l(:field_estimated_hours), issue_estimated_hours_details(@issue), :class => 'estimated-hours'
|
||||
end
|
||||
if User.current.allowed_to?(:view_time_entries, @project) && @issue.total_spent_hours > 0
|
||||
rows.right l(:label_spent_time), issue_spent_hours_details(@issue), :class => 'spent-time'
|
||||
end
|
||||
end %>
|
||||
<%= render_half_width_custom_fields_rows(@issue) %>
|
||||
<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
|
||||
</div>
|
||||
|
||||
<% if @issue.description? %>
|
||||
<hr />
|
||||
<div class="description">
|
||||
<div class="contextual">
|
||||
<%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if @issue.notes_addable? %>
|
||||
<%= link_to l(:label_history), 'javascript:void(0)', :class => 'icon icon-history', :onclick => '$("html, body").animate({scrollTop: $("#history").offset().top - 53}, 1000);' %>
|
||||
</div>
|
||||
|
||||
<p><strong><%=l(:field_description)%></strong></p>
|
||||
<div class="wiki">
|
||||
<%= textilizable @issue, :description, :attachments => @issue.attachments %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @issue.attachments.any? %>
|
||||
<hr />
|
||||
<div class="files">
|
||||
<p><strong><%=l(:label_attachment_plural)%></strong></p>
|
||||
<%= link_to_attachments @issue, :thumbnails => true %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render_full_width_custom_fields_rows(@issue) %>
|
||||
|
||||
<%= call_hook(:view_issues_show_description_bottom, :issue => @issue) %>
|
||||
|
||||
<% if !@issue.leaf? || User.current.allowed_to?(:manage_subtasks, @project) %>
|
||||
<hr />
|
||||
<div id="issue_tree">
|
||||
<%= render :partial => 'subtasks' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if @relations.present? || User.current.allowed_to?(:manage_issue_relations, @project) %>
|
||||
<hr />
|
||||
<div id="relations">
|
||||
<%= render :partial => 'relations' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<%= render partial: 'action_menu_edit' if User.current.wants_comments_in_reverse_order? %>
|
||||
|
||||
<div id="history">
|
||||
<%= render_tabs issue_history_tabs, issue_history_default_tab %>
|
||||
</div>
|
||||
|
||||
<%= render partial: 'action_menu_edit' unless User.current.wants_comments_in_reverse_order? %>
|
||||
|
||||
<% other_formats_links do |f| %>
|
||||
<%= f.link_to 'Atom', :url => {:key => User.current.atom_key} %>
|
||||
<%= f.link_to 'PDF' %>
|
||||
<% end %>
|
||||
|
||||
<% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<%= render :partial => 'issues/sidebar' %>
|
||||
|
||||
<% if User.current.allowed_to?(:add_issue_watchers, @project) ||
|
||||
(@issue.watchers.present? && User.current.allowed_to?(:view_issue_watchers, @project)) %>
|
||||
<div id="watchers">
|
||||
<%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.atom_key}, :title => "#{@issue.project} - #{@issue.tracker} ##{@issue.id}: #{@issue.subject}") %>
|
||||
<% end %>
|
||||
|
||||
<%= context_menu %>
|
||||
14
plugins/000_redmine_x_ux_upgrade/app/views/layouts/_logo.html.erb
Executable file
14
plugins/000_redmine_x_ux_upgrade/app/views/layouts/_logo.html.erb
Executable file
@@ -0,0 +1,14 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<a class="projectino-logo" href="<%= home_path %>">
|
||||
<%= render :partial => 'common/image', :locals => {:path => RedmineXUxUpgrade.logo_url, :alt => "Logo"} %>
|
||||
</a>
|
||||
@@ -0,0 +1,37 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<a id="top-menu-hamburger-trigger" class="far fa fa-bars"></a>
|
||||
<div id="top-menu-hamburger">
|
||||
<h2><span><%= l(:top_menu_hamburger_user) %></span></h2>
|
||||
<%= content_tag 'ul' do %>
|
||||
<%= content_tag('li',
|
||||
link_to_user_with_text(
|
||||
User.current,
|
||||
:text => l(:top_menu_hamburger_activity)
|
||||
)
|
||||
) if User.current.logged? %>
|
||||
<% end %>
|
||||
<%= render_menu :account_menu -%>
|
||||
|
||||
<% if User.current.admin? %>
|
||||
<h2><span><%= l(:top_menu_hamburger_additional_features) %></span></h2>
|
||||
<%= render_menu :top_menu_hamburger_additional_features -%>
|
||||
<% end %>
|
||||
|
||||
<%if render_menu :top_menu_hamburger_plugins %>
|
||||
<h2><span><%= l(:top_menu_hamburger_plugins) %></span></h2>
|
||||
<%= render_menu :top_menu_hamburger_plugins %>
|
||||
<%end%>
|
||||
|
||||
<h2><span><%= l(:top_menu_hamburger_system) %></span></h2>
|
||||
<%= render_menu :top_menu_hamburger_system -%>
|
||||
</div>
|
||||
198
plugins/000_redmine_x_ux_upgrade/app/views/layouts/base.html.erb
Normal file
198
plugins/000_redmine_x_ux_upgrade/app/views/layouts/base.html.erb
Normal file
@@ -0,0 +1,198 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%= current_language %>">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<title><%= html_title %></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<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.13.2', 'tribute-5.1.3', 'application', 'responsive', :media => 'all' %>
|
||||
<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
|
||||
|
||||
<%#= Translation of strings and relative path for theme.js and standard_theme.js %>
|
||||
<% theme_js_scope = { scope: :theme_js } %>
|
||||
<% standard_theme_js_scope = { scope: :standard_theme_js } %>
|
||||
|
||||
<script>
|
||||
window.I18nUxUpgradeJs = {
|
||||
filtersAndOptions: '<%= l(:filters_and_options, theme_js_scope) %>',
|
||||
areYouSure: '<%= l(:text_are_you_sure) %>',
|
||||
openAttachmentsBtn: '<%= l(:open_attachments_button, standard_theme_js_scope) %>',
|
||||
closeAttachmentsBtn: '<%= l(:close_attachments_button, standard_theme_js_scope) %>',
|
||||
};
|
||||
window.redmineRelativePath = '<%= Redmine::Utils::relative_url_root %>';
|
||||
window.userId = '<%= User.current.id %>';
|
||||
</script>
|
||||
|
||||
<%= javascript_heads %>
|
||||
<%= heads_for_theme %>
|
||||
<%= heads_for_auto_complete(@project) %>
|
||||
<%= call_hook :view_layouts_base_html_head %>
|
||||
<%#= page specific tags %>
|
||||
<%= yield :header_tags -%>
|
||||
|
||||
<%#= include extension-projectino.css which hides some redmine items in views when
|
||||
projectino is delivered as SAAS => if Projectino Extensions plugin is installed %>
|
||||
<% if Redmine::Plugin.installed?(:projectino_extensions) %>
|
||||
<%= stylesheet_link_tag 'extension-projectino.css', plugin: '000_redmine_x_ux_upgrade' %>
|
||||
<% end %>
|
||||
|
||||
<%#= include extension-redminex.css which hides some redmine items in views when
|
||||
redmine x is delivered as SAAS => if RedmineX Extensions plugin is installed %>
|
||||
<% if Redmine::Plugin.installed?(:redmine_x_extensions) %>
|
||||
<%= stylesheet_link_tag 'extension-redminex.css', plugin: '000_redmine_x_ux_upgrade' %>
|
||||
<% end %>
|
||||
|
||||
<%#= if user sets other theme than redminex_theme, load following css to fix styling bugs caused by
|
||||
removal of styles included in the redminex theme %>
|
||||
<% unless Setting.ui_theme == 'redminex_theme' %>
|
||||
<%= stylesheet_link_tag 'redminex_ux_upgrade_standard_themes.css', plugin: '000_redmine_x_ux_upgrade' %>
|
||||
<% end %>
|
||||
|
||||
<%#= UX Upgrade plugin js and css %>
|
||||
<%= javascript_include_tag('redmine_x_ux_upgrade.min.js', plugin: '000_redmine_x_ux_upgrade', type: 'module') %>
|
||||
<%= stylesheet_link_tag 'select2.min.css', plugin: '000_redmine_x_ux_upgrade' %>
|
||||
<%= javascript_include_tag 'select2.min.js', plugin: '000_redmine_x_ux_upgrade' %>
|
||||
</head>
|
||||
|
||||
<%# Hide top menu and navbar if authenttication required on login screen %>
|
||||
<% if Setting.login_required == '1' %>
|
||||
<body class="<%= body_css_classes %> authentification">
|
||||
<% else %>
|
||||
<body class="<%= body_css_classes %>">
|
||||
<% end %>
|
||||
<%= 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">
|
||||
<%#= Search form is replaced with jump to project, jump to project
|
||||
object is moved to mobile menu using theme.js %>
|
||||
<%#= form_tag(search_path(id: @project), :method => :get ) do %>
|
||||
<%#= hidden_field_tag(controller.default_search_scope, 1, :id => nil) if controller.default_search_scope %>
|
||||
<%#= label_tag 'flyout-search', '⚲'.html_safe, :class => 'search-magnifier search-magnifier--flyout' %>
|
||||
<%#= text_field_tag 'q', @question, :id => 'flyout-search', :class => 'small js-search-input', :placeholder => l(:label_search) %>
|
||||
<%# end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if User.current.logged? %>
|
||||
<div class="flyout-menu__avatar <% if !Setting.gravatar_enabled? %>flyout-menu__avatar--no-avatar<% end %>">
|
||||
<% if Setting.gravatar_enabled? %>
|
||||
<%= link_to(avatar(User.current, :size => "80"), user_path(User.current)) %>
|
||||
<% end %>
|
||||
<%= link_to_user(User.current, :format => :username) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%#= Project menu section removed, because project menu is not moved to
|
||||
mobile menu %>
|
||||
<%# if display_main_menu?(@project) %>
|
||||
<%#= <h3><%#= l(:label_project) %><%#=</h3> %>
|
||||
<%#= <span class="js-project-menu"></span> %>
|
||||
<%# end %>
|
||||
|
||||
<h3><%= l(:label_general) %></h3>
|
||||
<span class="js-general-menu"></span>
|
||||
|
||||
<span class="js-sidebar flyout-menu__sidebar"></span>
|
||||
|
||||
<%#= Label of profile menu removed - profile menu is part of hamburger menu
|
||||
which is moved behind js-profile-menu on mobile %>
|
||||
<%#= <h3><%#= l(:label_profile) %><%#=</h3> %>
|
||||
<span class="js-profile-menu"></span>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="actionbar">
|
||||
<%= render_menu(:new_entity_menu)-%>
|
||||
</div>
|
||||
<div id="top-menu">
|
||||
<%= render "layouts/top_menu_hamburger" %>
|
||||
<%= render "layouts/logo"%>
|
||||
<%= render_menu :projectino_top_menu if User.current.logged? || !Setting.login_required? -%>
|
||||
</div>
|
||||
|
||||
<div id="header">
|
||||
|
||||
<a href="#" class="mobile-toggle-button js-flyout-menu-toggle-button"></a>
|
||||
|
||||
<% if User.current.logged? || !Setting.login_required? %>
|
||||
<div id="quick-search">
|
||||
<%= form_tag(search_path(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 %>
|
||||
<%#= Only open issues search options should be on by default for projectino users %>
|
||||
<% if Redmine::Plugin.installed?(:projectino_extensions) %>
|
||||
<%= hidden_field_tag('open_issues', 1) %>
|
||||
<% end %>
|
||||
|
||||
<label for='q'>
|
||||
<%= link_to l(:label_search), search_path(id: @project, :scope => default_search_project_scope), :accesskey => accesskey(:search) %>:
|
||||
</label>
|
||||
<%= text_field_tag 'q', @question, :size => 20, :class => 'small', :accesskey => accesskey(:quick_search),
|
||||
:data => {
|
||||
:auto_complete => true
|
||||
},
|
||||
:placeholder => l(:label_search)
|
||||
%>
|
||||
<% end %>
|
||||
<%= render_project_jump_box %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<a href="/" class="mobile-home-button">
|
||||
<img alt="Logo" src="<%= Redmine::Utils::relative_url_root %>/themes/redminex_theme/images/logo-only.svg">
|
||||
</a>
|
||||
|
||||
<h1><%= page_header_title %></h1>
|
||||
|
||||
<%#= #main-menu renamed to #main-menu2 to disable moving of the projectmenu to the mobile menu %>
|
||||
<% if display_main_menu?(@project) %>
|
||||
<div id="main-menu2" class="tabs">
|
||||
<%= 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>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div id="main" class="<%= sidebar_content? ? '' : 'nosidebar' %>">
|
||||
<div id="sidebar">
|
||||
<%= yield :sidebar %>
|
||||
<%= view_layouts_base_sidebar_hook_response %>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<%= render_flash_messages %>
|
||||
<%= yield %>
|
||||
<%= call_hook :view_layouts_base_content %>
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> © 2006-2022 Jean-Philippe Lang
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
|
||||
<div id="ajax-modal" style="display:none;"></div>
|
||||
</div>
|
||||
<%= call_hook :view_layouts_base_body_bottom %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,89 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= additional_emails_link(@user) %>
|
||||
<%= link_to(l(:button_change_password), {:action => 'password'}, :class => 'icon icon-passwd') if @user.change_password_allowed? %>
|
||||
<%= call_hook(:view_my_account_contextual, :user => @user)%>
|
||||
</div>
|
||||
|
||||
<h2>
|
||||
<%= avatar_edit_link(@user, :size => "50") %>
|
||||
<%=l(:label_my_account)%>
|
||||
</h2>
|
||||
|
||||
<%= error_messages_for 'user' %>
|
||||
|
||||
<%= labelled_form_for :user, @user,
|
||||
:url => { :action => "account" },
|
||||
:html => { :id => 'my_account_form',
|
||||
:method => :put, :multipart => true } do |f| %>
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<fieldset class="box tabular">
|
||||
<legend><%=l(:label_information_plural)%></legend>
|
||||
<p><%= f.text_field :firstname, :required => true %></p>
|
||||
<p><%= f.text_field :lastname, :required => true %></p>
|
||||
<p><%= f.text_field :mail, :required => true %></p>
|
||||
<% unless @user.force_default_language? %>
|
||||
<p><%= f.select :language, lang_options_for_select %></p>
|
||||
<% end %>
|
||||
<% if Setting.twofa? -%>
|
||||
<p>
|
||||
<label><%=l :setting_twofa -%></label>
|
||||
<% if @user.twofa_active? %>
|
||||
<%=l 'twofa_currently_active', twofa_scheme_name: l("twofa__#{@user.twofa_scheme}__name") -%><br/>
|
||||
<%= link_to l('button_disable'), { controller: 'twofa', action: 'deactivate_init', scheme: @user.twofa_scheme }, method: :post -%><br/>
|
||||
<%= link_to l('twofa_generate_backup_codes'), { controller: 'twofa_backup_codes', action: 'init' }, method: :post, data: { confirm: Redmine::Twofa.for_user(User.current).backup_codes.any? ? t('twofa_text_generate_backup_codes_confirmation') : nil } -%>
|
||||
<% else %>
|
||||
<% Redmine::Twofa.available_schemes.each do |s| %>
|
||||
<%= link_to l("twofa__#{s}__label_activate"), { controller: 'twofa', action: 'activate_init', scheme: s }, method: :post -%><br/>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end -%>
|
||||
|
||||
<% @user.custom_field_values.select(&:editable?).each do |value| %>
|
||||
<p><%= custom_field_tag_with_label :user, value %></p>
|
||||
<% end %>
|
||||
<%= call_hook(:view_my_account, :user => @user, :form => f) %>
|
||||
</fieldset>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="splitcontentright">
|
||||
<fieldset class="box">
|
||||
<legend><%=l(:field_mail_notification)%></legend>
|
||||
<%= render :partial => 'users/mail_notifications' %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box">
|
||||
<legend><%=l(:label_auto_watch_on)%></legend>
|
||||
<%= render :partial => 'users/auto_watch_on' %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box tabular">
|
||||
<legend><%=l(:label_preferences)%></legend>
|
||||
<%= render :partial => 'users/preferences' %>
|
||||
<%= call_hook(:view_my_account_preferences, :user => @user, :form => f) %>
|
||||
</fieldset>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="projectino-controls mobile-show"><%= submit_tag l(:button_save) %></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<%= render :partial => 'sidebar' %>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_my_account)) -%>
|
||||
23
plugins/000_redmine_x_ux_upgrade/app/views/news/edit.html.erb
Executable file
23
plugins/000_redmine_x_ux_upgrade/app/views/news/edit.html.erb
Executable file
@@ -0,0 +1,23 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%=l(:label_news)%></h2>
|
||||
|
||||
<%= labelled_form_for @news, :html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= stylesheet_link_tag 'scm' %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,62 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= link_to(l(:label_news_new),
|
||||
(@project ? project_news_index_path(@project) : news_index_path),
|
||||
:class => 'icon icon-add add-news-link',
|
||||
:onclick => 'showAndScrollTo("add-news", "news_title"); return false;') if User.current.allowed_to?(:manage_news, @project, global: true) %>
|
||||
<%= watcher_link(@project.enabled_module('news'), User.current) if @project && User.current.logged? %>
|
||||
</div>
|
||||
|
||||
<div id="add-news" style="display:none;">
|
||||
<h2><%=l(:label_news_new)%></h2>
|
||||
<%= labelled_form_for @news, :url => (@project ? project_news_index_path(@project) : news_index_path),
|
||||
:html => { :id => 'news-form', :multipart => true } do |f| %>
|
||||
<%= render :partial => 'news/form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= link_to l(:button_cancel), "#", :onclick => '$("#add-news").hide()' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h2><%=l(:label_news_plural)%></h2>
|
||||
|
||||
<% if @newss.empty? %>
|
||||
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||
<% else %>
|
||||
<% @newss.each do |news| %>
|
||||
<article class="news-article">
|
||||
<header>
|
||||
<h3><%= avatar(news.author) %><%= link_to_project(news.project) + ': ' unless news.project == @project %>
|
||||
<%= link_to h(news.title), news_path(news) %>
|
||||
<%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %></h3>
|
||||
<p class="author"><%= authoring news.created_on, news.author %></p>
|
||||
</header>
|
||||
<div class="wiki">
|
||||
<%= textilizable(news, :description) %>
|
||||
</div>
|
||||
</article>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<span class="pagination"><%= pagination_links_full @news_pages %></span>
|
||||
|
||||
<% other_formats_links do |f| %>
|
||||
<%= f.link_to 'Atom', :url => {:project_id => @project, :key => User.current.atom_key} %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= auto_discovery_link_tag(:atom, _project_news_path(@project, :key => User.current.atom_key, :format => 'atom')) %>
|
||||
<%= stylesheet_link_tag 'scm' %>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_news_plural)) -%>
|
||||
20
plugins/000_redmine_x_ux_upgrade/app/views/news/new.html.erb
Executable file
20
plugins/000_redmine_x_ux_upgrade/app/views/news/new.html.erb
Executable file
@@ -0,0 +1,20 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%=l(:label_news_new)%></h2>
|
||||
|
||||
<%= labelled_form_for @news, :url => (@project ? project_news_index_path(@project) : news_index_path),
|
||||
:html => { :id => 'news-form', :multipart => true } do |f| %>
|
||||
<%= render :partial => 'news/form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
</div>
|
||||
<% end %>
|
||||
84
plugins/000_redmine_x_ux_upgrade/app/views/news/show.html.erb
Executable file
84
plugins/000_redmine_x_ux_upgrade/app/views/news/show.html.erb
Executable file
@@ -0,0 +1,84 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= watcher_link(@news, User.current) %>
|
||||
<%= link_to(l(:button_edit),
|
||||
edit_news_path(@news),
|
||||
:class => 'icon icon-edit',
|
||||
:accesskey => accesskey(:edit),
|
||||
:onclick => '$("#edit-news").show(); return false;') if User.current.allowed_to?(:manage_news, @project) %>
|
||||
<%= delete_link news_path(@news) if User.current.allowed_to?(:manage_news, @project) %>
|
||||
</div>
|
||||
|
||||
<h2><%= avatar(@news.author) %> <%=h @news.title %></h2>
|
||||
|
||||
<% if authorize_for('news', 'edit') %>
|
||||
<div id="edit-news" style="display:none;">
|
||||
<%= labelled_form_for :news, @news, :url => news_path(@news),
|
||||
:html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<%= link_to l(:button_cancel), "#", :onclick => '$("#edit-news").hide(); return false;' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<p><% unless @news.summary.blank? %><em><%= @news.summary %></em><br /><% end %>
|
||||
<span class="author"><%= authoring @news.created_on, @news.author %></span></p>
|
||||
<div class="wiki">
|
||||
<%= textilizable(@news, :description) %>
|
||||
</div>
|
||||
<%= link_to_attachments @news %>
|
||||
<br />
|
||||
|
||||
<div id="comments" style="margin-bottom:16px;">
|
||||
<h3 class="comments"><%= l(:label_comment_plural) %></h3>
|
||||
<% if @news.commentable? && @comments.size >= 3 %>
|
||||
<p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments", :scroll => "comment_comments" %></p>
|
||||
<% end %>
|
||||
<% @comments.each do |comment| %>
|
||||
<% next if comment.new_record? %>
|
||||
<div class="contextual">
|
||||
<%= link_to_if_authorized l(:button_delete), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
|
||||
:data => {:confirm => l(:text_are_you_sure)}, :method => :delete,
|
||||
:title => l(:button_delete),
|
||||
:class => 'icon-only icon-del' %>
|
||||
</div>
|
||||
<h4><%= avatar(comment.author) %><%= authoring comment.created_on, comment.author %></h4>
|
||||
<div class="wiki">
|
||||
<%= textilizable(comment.comments) %>
|
||||
</div>
|
||||
<% end if @comments.any? %>
|
||||
</div>
|
||||
|
||||
<% if @news.commentable? %>
|
||||
<p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %></p>
|
||||
<%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %>
|
||||
<div class="box">
|
||||
<%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit',
|
||||
:data => {
|
||||
:auto_complete => true
|
||||
}
|
||||
%>
|
||||
<%= wikitoolbar_for 'comment_comments', preview_news_path(:project_id => @project, :id => @news) %>
|
||||
</div>
|
||||
<div class="projectino-controls"><%= submit_tag l(:button_add) %></div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% html_title @news.title -%>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= stylesheet_link_tag 'scm' %>
|
||||
<% end %>
|
||||
17
plugins/000_redmine_x_ux_upgrade/app/views/projects/_edit.html.erb
Executable file
17
plugins/000_redmine_x_ux_upgrade/app/views/projects/_edit.html.erb
Executable file
@@ -0,0 +1,17 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= labelled_form_for @project, :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,72 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="project-aggregate box">
|
||||
<h3 class="icon icon-project"><%= l(:project_aggregator_box_title) %></h3>
|
||||
|
||||
<!-- Project completion by spent time including subprojects -->
|
||||
<div class="project-completion project-item">
|
||||
<div class="label"><%= l(:project_completion) %></div>
|
||||
<% if completion > 100 %>
|
||||
<div class="value overflow"><%= completion %>%</div>
|
||||
<% else %>
|
||||
<div class="value"><%= completion %>%</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<!-- Project completion by spent time including subprojects -->
|
||||
<div class="project-done-ratio project-item">
|
||||
<div class="label"><%= l(:project_progress) %></div>
|
||||
<div class="value"><%= progress %>%</div>
|
||||
</div>
|
||||
|
||||
<!-- Project start date -->
|
||||
<div class="project-start-date project-item">
|
||||
<div class="label"><%= l(:project_start_date) %></div>
|
||||
<div class="value"><%= @project.start_date ? format_date(@project.start_date) : 'N/A' %></div>
|
||||
</div>
|
||||
|
||||
<!-- Project start date -->
|
||||
<div class="project-due-date project-item">
|
||||
<div class="label"><%= l(:project_due_date) %></div>
|
||||
<div class="value"><%= @project.due_date ? format_date(@project.due_date) : 'N/A' %></div>
|
||||
</div>
|
||||
|
||||
<!-- Estimated hours including subprojects -->
|
||||
<div class="estimated-hours project-item">
|
||||
<div class="label"><%= l(:field_estimated_hours) %></div>
|
||||
<div class="value">
|
||||
<%= l(:label_f_hour_plural, @total_estimated_hours ? '%.2f' % @total_estimated_hours : '%.2f' % 0) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Total spent time including subprojects -->
|
||||
<div class="spent-time project-item">
|
||||
<div class="label"><%= l(:label_spent_time) %></div>
|
||||
<div class="value">
|
||||
<%= l(:label_f_hour_plural, @total_hours ? '%.2f' % @total_hours: '%.2f' % 0) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- List of subprojects (visible only if there are some) -->
|
||||
<% unless @subprojects&.count&.zero? %>
|
||||
<div class="subprojects project-item">
|
||||
<div class="label"><%= l(:label_subproject_plural) %></div>
|
||||
<div class="value">
|
||||
<ul>
|
||||
<% @subprojects.each do |project| %>
|
||||
<li><%= link_to(project.name, project_path(project)) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
20
plugins/000_redmine_x_ux_upgrade/app/views/projects/new.html.erb
Executable file
20
plugins/000_redmine_x_ux_upgrade/app/views/projects/new.html.erb
Executable file
@@ -0,0 +1,20 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title l(:label_project_new) %>
|
||||
|
||||
<%= labelled_form_for @project, :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,57 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= link_to(l(:button_reset), project_enumerations_path(@project),
|
||||
:method => :delete,
|
||||
:data => {:confirm => l(:text_are_you_sure)},
|
||||
:class => 'icon icon-del') %>
|
||||
<% if User.current.admin? %>
|
||||
<%= link_to l(:label_administration), enumerations_path, :class => "icon icon-settings" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= form_tag(project_enumerations_path(@project), :method => :put, :class => "tabular") do %>
|
||||
|
||||
<table class="list">
|
||||
<thead><tr>
|
||||
<th><%= l(:field_name) %></th>
|
||||
<th><%= l(:enumeration_system_activity) %></th>
|
||||
<% TimeEntryActivity.new.available_custom_fields.each do |value| %>
|
||||
<th><%= value.name %></th>
|
||||
<% end %>
|
||||
<th><%= toggle_checkboxes_link('input.enumerations_active') %> <%= l(:field_active) %></th>
|
||||
</tr></thead>
|
||||
|
||||
<% @project.activities(true).each do |enumeration| %>
|
||||
<%= fields_for "enumerations[#{enumeration.id}]", enumeration do |ff| %>
|
||||
<tr>
|
||||
<td class="name">
|
||||
<%= ff.hidden_field :parent_id, :value => enumeration.id unless enumeration.project %>
|
||||
<%= enumeration %>
|
||||
</td>
|
||||
<td class="tick"><%= checked_image !enumeration.project %></td>
|
||||
<% enumeration.custom_field_values.each do |value| %>
|
||||
<td>
|
||||
<%= custom_field_tag "enumerations[#{enumeration.id}]", value %>
|
||||
</td>
|
||||
<% end %>
|
||||
<td>
|
||||
<%= ff.check_box :active, :class => 'enumerations_active' %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,64 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= labelled_form_for @project, html: {id: 'project_issue_tracking' } do |f| %>
|
||||
<%= hidden_field_tag 'tab', 'issues' %>
|
||||
|
||||
<% unless @trackers.empty? %>
|
||||
<fieldset class="box tabular" id="project_trackers"><legend><%= toggle_checkboxes_link('#project_trackers input[type=checkbox]') %><%= l(:label_tracker_plural)%></legend>
|
||||
<% if User.current.admin? %>
|
||||
<div class="contextual"><%= link_to l(:label_administration), trackers_path, :class => "icon icon-settings" %></div>
|
||||
<% end %>
|
||||
<% @trackers.each do |tracker| %>
|
||||
<label class="floating">
|
||||
<%= check_box_tag 'project[tracker_ids][]', tracker.id, @project.trackers.to_a.include?(tracker), :id => nil %>
|
||||
<%= tracker_name_tag tracker %>
|
||||
</label>
|
||||
<% end %>
|
||||
<%= hidden_field_tag 'project[tracker_ids][]', '' %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
<% unless @issue_custom_fields.empty? %>
|
||||
<fieldset class="box tabular" id="project_issue_custom_fields"><legend><%= toggle_checkboxes_link('#project_issue_custom_fields input[type=checkbox]:enabled') %><%=l(:label_custom_field_plural)%></legend>
|
||||
<% if User.current.admin? %>
|
||||
<div class="contextual"><%= link_to l(:label_administration), custom_fields_path, :class => "icon icon-settings" %></div>
|
||||
<% end %>
|
||||
<% all_issue_custom_field_ids = @project.all_issue_custom_fields.ids %>
|
||||
<% @issue_custom_fields.each do |custom_field| %>
|
||||
<label class="floating">
|
||||
<%= check_box_tag 'project[issue_custom_field_ids][]', custom_field.id, (all_issue_custom_field_ids.include? custom_field.id),
|
||||
:disabled => (custom_field.is_for_all? ? "disabled" : nil),
|
||||
:id => nil %>
|
||||
<%= custom_field_name_tag(custom_field) %>
|
||||
</label>
|
||||
<% end %>
|
||||
<%= hidden_field_tag 'project[issue_custom_field_ids][]', '' %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
<div class="box tabular">
|
||||
<% if @project.safe_attribute?('default_version_id') %>
|
||||
<p><%= f.select :default_version_id, project_default_version_options(@project), include_blank: l(:label_none) %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @project.safe_attribute?('default_assigned_to_id') %>
|
||||
<p><%= f.select :default_assigned_to_id, project_default_assigned_to_options(@project), include_blank: l(:label_none) %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @project.safe_attribute?('default_issue_query_id') %>
|
||||
<p><%= f.select :default_issue_query_id, project_default_issue_query_options(@project), include_blank: l(:label_none) %><em class="info"><%=l 'text_allowed_queries_to_select' %></em></p>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<p><%= submit_tag l(:button_save) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,176 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= bookmark_link @project %>
|
||||
|
||||
<%= actions_dropdown do %>
|
||||
<% if User.current.allowed_to?(:add_subprojects, @project) %>
|
||||
<%= link_to l(:label_subproject_new), new_project_path(:parent_id => @project), :class => 'icon icon-add' %>
|
||||
<% end %>
|
||||
<%# Copy project directly from the project show %>
|
||||
<% if User.current.allowed_to?(:add_projects, nil, { global: true }) %>
|
||||
<% if Redmine::Plugin.installed?(:redmine_x_project_copy)%>
|
||||
<%= link_to l(:button_copy), redmine_x_project_copy_path(@project), :class => 'icon icon-copy' %>
|
||||
<% else %>
|
||||
<%= link_to l(:button_copy), copy_project_path(@project), :class => 'icon icon-copy' %>
|
||||
<% end %>
|
||||
<% end%>
|
||||
<% if User.current.allowed_to?(:close_project, @project) %>
|
||||
<% if @project.active? %>
|
||||
<%= link_to l(:button_close), close_project_path(@project), :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-lock' %>
|
||||
<% else %>
|
||||
<%= link_to l(:button_reopen), reopen_project_path(@project), :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-unlock' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @project.deletable? %>
|
||||
<%= link_to l(:button_delete), project_path(@project), :method => :delete, :class => 'icon icon-del' %>
|
||||
<% end %>
|
||||
<%= link_to_if_authorized l(:label_settings),
|
||||
{:controller => 'projects', :action => 'settings', :id => @project},
|
||||
:class => 'icon icon-settings' if User.current.allowed_to?(:edit_project, @project) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h2><%=l(:label_overview)%></h2>
|
||||
|
||||
<% unless @project.active? %>
|
||||
<p class="warning"><span class="icon icon-lock"><%= l(:text_project_closed) %></span></p>
|
||||
<% end %>
|
||||
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<% if @project.description.present? %>
|
||||
<div class="wiki">
|
||||
<%= textilizable @project.description %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @project.homepage.present? || @project.visible_custom_field_values.any? { |o| o.value.present? } %>
|
||||
<ul>
|
||||
<% unless @project.homepage.blank? %>
|
||||
<li><span class="label"><%=l(:field_homepage)%>:</span> <%= link_to_if uri_with_safe_scheme?(@project.homepage), @project.homepage, @project.homepage %></li>
|
||||
<% end %>
|
||||
<% render_custom_field_values(@project) do |custom_field, formatted| %>
|
||||
<li class="<%= custom_field.css_classes %>"><span class="label"><%= custom_field.name %>:</span> <%= formatted %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<% if User.current.allowed_to?(:view_issues, @project) %>
|
||||
<div class="issues box">
|
||||
<h3 class="icon icon-issue">
|
||||
<%=l(:label_issue_tracking)%>
|
||||
<%= link_to l(:label_details),
|
||||
project_issues_report_details_path(@project, :detail => 'tracker'),
|
||||
:class => 'icon-only icon-zoom-in',
|
||||
:title => l(:label_details) %>
|
||||
</h3>
|
||||
<% if @trackers.present? %>
|
||||
<table class="list issue-report">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><%=l(:label_open_issues_plural)%></th>
|
||||
<th><%=l(:label_closed_issues_plural)%></th>
|
||||
<th><%=l(:label_total)%></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @trackers.each do |tracker| %>
|
||||
<tr>
|
||||
<td class="name">
|
||||
<%= link_to tracker.name, project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id), :title => tracker.description %>
|
||||
</td>
|
||||
<td>
|
||||
<%= link_to @open_issues_by_tracker[tracker].to_i, project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id) %>
|
||||
</td>
|
||||
<td>
|
||||
<%= link_to (@total_issues_by_tracker[tracker].to_i - @open_issues_by_tracker[tracker].to_i), project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id, :status_id => 'c') %>
|
||||
</td>
|
||||
<td class="total">
|
||||
<%= link_to @total_issues_by_tracker[tracker].to_i, project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id, :status_id => '*') %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
<p>
|
||||
<%= link_to l(:label_issue_view_all), project_issues_path(@project, :set_filter => 1) %>
|
||||
| <%= link_to l(:field_summary), project_issues_report_path(@project) %>
|
||||
<% if User.current.allowed_to?(:view_calendar, @project, :global => true) %>
|
||||
| <%= link_to l(:label_calendar), project_calendar_path(@project) %>
|
||||
<% end %>
|
||||
<% if User.current.allowed_to?(:view_gantt, @project, :global => true) %>
|
||||
| <%= link_to l(:label_gantt), project_gantt_path(@project) %>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if User.current.allowed_to?(:view_time_entries, @project) %>
|
||||
<div class="spent_time box">
|
||||
<h3 class="icon icon-time"><%= l(:label_time_tracking) %></h3>
|
||||
<ul>
|
||||
<% if @total_estimated_hours.present? %>
|
||||
<li><%= l(:field_estimated_hours) %>: <%= l_hours(@total_estimated_hours) %>
|
||||
<% end %>
|
||||
<% if @total_hours.present? %>
|
||||
<li><%= l(:label_spent_time) %>: <%= l_hours(@total_hours) %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<p>
|
||||
<% if User.current.allowed_to?(:log_time, @project) %>
|
||||
<%= link_to l(:button_log_time), new_project_time_entry_path(@project) %> |
|
||||
<% end %>
|
||||
<%= link_to(l(:label_details), project_time_entries_path(@project)) %> |
|
||||
<%= link_to(l(:label_report), report_project_time_entries_path(@project)) %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= call_hook(:view_projects_show_left, :project => @project) %>
|
||||
</div>
|
||||
|
||||
<div class="splitcontentright">
|
||||
<% if @news.any? && authorize_for('news', 'index') %>
|
||||
<div class="news box">
|
||||
<h3 class="icon icon-news"><%=l(:label_news_latest)%></h3>
|
||||
<%= render :partial => 'news/news', :collection => @news %>
|
||||
<p><%= link_to l(:label_news_view_all), project_news_index_path(@project) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => 'members_box' %>
|
||||
|
||||
<% if @subprojects.any? %>
|
||||
<div class="projects box">
|
||||
<h3 class="icon icon-projects"><%=l(:label_subproject_plural)%></h3>
|
||||
<ul class="subprojects">
|
||||
<% @subprojects.each do |project| %>
|
||||
<li><%= link_to(project.name, project_path(project), :class => project.css_classes).html_safe %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= call_hook(:view_projects_show_right, :project => @project) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<%= call_hook(:view_projects_show_sidebar_bottom, :project => @project) %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :key => User.current.atom_key}) %>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_overview)) -%>
|
||||
@@ -0,0 +1,19 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%= l(:label_query) %></h2>
|
||||
|
||||
<%= form_tag(query_path(@query), :method => :put, :id => "query-form") do %>
|
||||
<%= render :partial => 'form', :locals => {:query => @query} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,20 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%= l(:label_query_new) %></h2>
|
||||
|
||||
<%= form_tag(@project ? project_queries_path(@project) : queries_path, :id => "query-form") do %>
|
||||
<%= hidden_field_tag 'type', @query.class.name %>
|
||||
<%= render :partial => 'form', :locals => {:query => @query} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
19
plugins/000_redmine_x_ux_upgrade/app/views/roles/edit.html.erb
Executable file
19
plugins/000_redmine_x_ux_upgrade/app/views/roles/edit.html.erb
Executable file
@@ -0,0 +1,19 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_role_plural), roles_path], @role.name %>
|
||||
|
||||
<%= labelled_form_for @role do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
19
plugins/000_redmine_x_ux_upgrade/app/views/roles/new.html.erb
Executable file
19
plugins/000_redmine_x_ux_upgrade/app/views/roles/new.html.erb
Executable file
@@ -0,0 +1,19 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_role_plural), roles_path], l(:label_role_new) %>
|
||||
|
||||
<%= labelled_form_for @role do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,113 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_role_plural), roles_path], l(:label_permissions_report) %>
|
||||
|
||||
<div class="hide-when-print">
|
||||
<fieldset id="filters" class="collapsible collapsed">
|
||||
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_filter_plural) %></legend>
|
||||
<div style="display: none;">
|
||||
<%= form_tag({}, :method => :get) do %>
|
||||
<fieldset>
|
||||
<legend><%= toggle_checkboxes_link('#filters input[type=checkbox]:enabled') %></legend>
|
||||
<% Role.sorted.to_a.each do |role| %>
|
||||
<label>
|
||||
<%= check_box_tag "ids[]", role.id, @roles.include?(role) %>
|
||||
<%= role.name %>
|
||||
</label>
|
||||
<% end %>
|
||||
</fieldset>
|
||||
<p>
|
||||
<%= submit_tag l(:button_apply), :name => nil %>
|
||||
<%= link_to l(:button_clear), permissions_roles_path, :class => 'icon icon-reload' %>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<%= form_tag(permissions_roles_path, :id => 'permissions_form') do %>
|
||||
<% @roles.each do |role| %>
|
||||
<%= hidden_field_tag "permissions[#{role.id}][]", '', :id => nil %>
|
||||
<% end %>
|
||||
<div class="autoscroll">
|
||||
<table class="list permissions">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%=l(:label_permissions)%></th>
|
||||
<% @roles.each do |role| %>
|
||||
<th>
|
||||
<%= link_to_function('',
|
||||
"toggleCheckboxesBySelector('input.role-#{role.id}')",
|
||||
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
|
||||
:class => 'icon-only icon-checked') %>
|
||||
<%= content_tag(role.builtin? ? 'em' : 'span', role.name) %>
|
||||
</th>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %>
|
||||
<% perms_by_module.keys.sort.each do |mod| %>
|
||||
<% unless mod.blank? %>
|
||||
<tr class="group open">
|
||||
<td>
|
||||
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
||||
<%= l_or_humanize(mod, :prefix => 'project_module_') %>
|
||||
</td>
|
||||
<% @roles.each do |role| %>
|
||||
<td class="role"><%= role.name %></td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% perms_by_module[mod].each do |permission| %>
|
||||
<% humanized_perm_name = l_or_humanize(permission.name, :prefix => 'permission_') %>
|
||||
<tr class="permission-<%= permission.name %>">
|
||||
<td class="name">
|
||||
<%= link_to_function('',
|
||||
"toggleCheckboxesBySelector('.permission-#{permission.name} input')",
|
||||
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
|
||||
:class => 'icon-only icon-checked') %>
|
||||
<%= humanized_perm_name %>
|
||||
</td>
|
||||
<% @roles.each do |role| %>
|
||||
<% if role.setable_permissions.include? permission %>
|
||||
<td title="<%= "#{humanized_perm_name} (#{role.name})" %>">
|
||||
<%= check_box_tag "permissions[#{role.id}][]", permission.name, (role.permissions.include? permission.name), :id => nil, :class => "role-#{role.id}" %>
|
||||
</td>
|
||||
<% else %>
|
||||
<td></td>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p><%= check_all_links 'permissions_form' %></p>
|
||||
<div class="projectino-controls">
|
||||
<p><%= submit_tag l(:button_save) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
<% other_formats_links do |f| %>
|
||||
<%= f.link_to_with_query_parameters 'CSV', {}, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
|
||||
<% end %>
|
||||
<div id="csv-export-options" style="display: none;">
|
||||
<h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
|
||||
<%= form_tag(permissions_roles_path(:format => 'csv'), :method => :get, :id => 'csv-export-form') do %>
|
||||
<%= export_csv_encoding_select_tag %>
|
||||
<p class="buttons">
|
||||
<%= submit_tag l(:button_export), :name => nil, :onclick => 'hideModal(this);', :data => {:disable_with => false} %>
|
||||
<%= link_to_function l(:button_cancel), 'hideModal(this);' %>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
22
plugins/000_redmine_x_ux_upgrade/app/views/settings/_api.html.erb
Executable file
22
plugins/000_redmine_x_ux_upgrade/app/views/settings/_api.html.erb
Executable file
@@ -0,0 +1,22 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'api'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_check_box :rest_api_enabled %></p>
|
||||
|
||||
<p><%= setting_check_box :jsonp_enabled %></p>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
35
plugins/000_redmine_x_ux_upgrade/app/views/settings/_attachments.html.erb
Executable file
35
plugins/000_redmine_x_ux_upgrade/app/views/settings/_attachments.html.erb
Executable file
@@ -0,0 +1,35 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'attachments'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_text_field :attachment_max_size, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
|
||||
|
||||
<p><%= setting_text_field :bulk_download_max_size, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
|
||||
|
||||
<p><%= setting_text_area :attachment_extensions_allowed %>
|
||||
<em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: txt, png</em></p>
|
||||
|
||||
<p><%= setting_text_area :attachment_extensions_denied %>
|
||||
<em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: js, swf</em></p>
|
||||
|
||||
<p><%= setting_text_field :file_max_size_displayed, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
|
||||
|
||||
<p><%= setting_text_field :diff_max_lines_displayed, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_text_field :repositories_encodings, :size => 60 %>
|
||||
<em class="info"><%= l(:text_comma_separated) %></em></p>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
70
plugins/000_redmine_x_ux_upgrade/app/views/settings/_authentication.html.erb
Executable file
70
plugins/000_redmine_x_ux_upgrade/app/views/settings/_authentication.html.erb
Executable file
@@ -0,0 +1,70 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'authentication'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_select :login_required, [[l(:label_login_required_yes), "1"],
|
||||
[l(:label_login_required_no), "0"]] %>
|
||||
<em class="info"><%= t(:text_login_required_html, anonymous_role_path: edit_role_path(Role.anonymous)) %></em>
|
||||
</p>
|
||||
|
||||
<p><%= setting_select :autologin, [[l(:label_disabled), 0]] + [1, 7, 30, 365].collect{|days| [l('datetime.distance_in_words.x_days', :count => days), days.to_s]} %></p>
|
||||
|
||||
<p><%= setting_select :self_registration, [[l(:label_disabled), "0"],
|
||||
[l(:label_registration_activation_by_email), "1"],
|
||||
[l(:label_registration_manual_activation), "2"],
|
||||
[l(:label_registration_automatic_activation), "3"]],
|
||||
:onchange =>
|
||||
"if (this.value != '0') { $('#settings_show_custom_fields_on_registration').removeAttr('disabled'); } else { $('#settings_show_custom_fields_on_registration').attr('disabled', true); }" %></p>
|
||||
|
||||
<p><%= setting_check_box :show_custom_fields_on_registration,
|
||||
:disabled => !Setting.self_registration? %></p>
|
||||
|
||||
<p><%= setting_text_field :password_min_length, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_multiselect :password_required_char_classes, Setting::PASSWORD_CHAR_CLASSES.keys.collect {|c| [l("label_password_char_class_#{c}"), c]} , :inline => true %></p>
|
||||
|
||||
<p>
|
||||
<%= setting_select :password_max_age, [[l(:label_disabled), 0]] + [7, 30, 60, 90, 180, 365].collect{|days| [l('datetime.distance_in_words.x_days', :count => days), days.to_s]} %>
|
||||
</p>
|
||||
|
||||
<p><%= setting_check_box :lost_password %></p>
|
||||
|
||||
<p>
|
||||
<%= setting_select :twofa, [[l(:label_disabled), "0"],
|
||||
[l(:label_optional), "1"],
|
||||
[l(:label_required_administrators), "3"],
|
||||
[l(:label_required_lower), "2"]] -%>
|
||||
<em class="info">
|
||||
<%= t 'twofa_hint_disabled_html', label: t(:label_disabled) -%><br/>
|
||||
<%= t 'twofa_hint_optional_html', label: t(:label_optional) -%><br/>
|
||||
<%= t 'twofa_hint_required_administrators_html', label: t(:label_required_administrators) -%><br/>
|
||||
<%= t 'twofa_hint_required_html', label: t(:label_required_lower) -%>
|
||||
</em>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<fieldset class="box">
|
||||
<legend><%= l(:label_session_expiration) %></legend>
|
||||
|
||||
<div class="tabular settings">
|
||||
<p><%= setting_select :session_lifetime, session_lifetime_options %></p>
|
||||
<p><%= setting_select :session_timeout, session_timeout_options %></p>
|
||||
</div>
|
||||
|
||||
<p><em class="info"><%= l(:text_session_expiration_settings) %></em></p>
|
||||
</fieldset>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
47
plugins/000_redmine_x_ux_upgrade/app/views/settings/_display.html.erb
Executable file
47
plugins/000_redmine_x_ux_upgrade/app/views/settings/_display.html.erb
Executable file
@@ -0,0 +1,47 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'display'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_select :ui_theme, Redmine::Themes.themes.collect {|t| [t.name, t.id]}, :blank => :label_default, :label => :label_theme %></p>
|
||||
|
||||
<p><%= setting_select :default_language, lang_options_for_select(false) %></p>
|
||||
|
||||
<p><%= setting_check_box :force_default_language_for_anonymous %></p>
|
||||
|
||||
<p><%= setting_check_box :force_default_language_for_loggedin %></p>
|
||||
|
||||
<p><%= setting_select :start_of_week, [[day_name(1),'1'], [day_name(6),'6'], [day_name(7),'7']], :blank => :label_language_based %></p>
|
||||
<% locale = User.current.language.blank? ? ::I18n.locale : User.current.language %>
|
||||
<p><%= setting_select :date_format, date_format_setting_options(locale), :blank => :label_language_based %></p>
|
||||
|
||||
<p><%= setting_select :time_format, Setting::TIME_FORMATS.collect {|f| [::I18n.l(Time.now, :locale => locale, :format => f), f]}, :blank => :label_language_based %></p>
|
||||
|
||||
<p><%= setting_select :timespan_format, [["%.2f" % 0.75, 'decimal'], ['0:45 h', 'minutes']], :blank => false %></p>
|
||||
|
||||
<p><%= setting_select :user_format, @options[:user_format] %></p>
|
||||
|
||||
<p><%= setting_check_box :gravatar_enabled, :data => {:enables => '#settings_gravatar_default'} %>
|
||||
<em class="info"><%= t(:text_avatar_server_config_html, :url => Redmine::Configuration['avatar_server_url']) %></em></p>
|
||||
|
||||
<p><%= setting_select :gravatar_default, gravatar_default_setting_options, :blank => :label_none %></p>
|
||||
|
||||
<p><%= setting_check_box :thumbnails_enabled, :data => {:enables => '#settings_thumbnails_size'} %></p>
|
||||
|
||||
<p><%= setting_text_field :thumbnails_size, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_select :new_item_menu_tab, [[l(:label_none), '0'], [l(:label_new_project_issue_tab_enabled), '1'], [l(:label_new_object_tab_enabled), '2']] %></p>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
69
plugins/000_redmine_x_ux_upgrade/app/views/settings/_general.html.erb
Executable file
69
plugins/000_redmine_x_ux_upgrade/app/views/settings/_general.html.erb
Executable file
@@ -0,0 +1,69 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_text_field :app_title, :size => 30 %></p>
|
||||
|
||||
<p><%= setting_text_area :welcome_text, :cols => 60, :rows => 5, :class => 'wiki-edit' %></p>
|
||||
<%= wikitoolbar_for 'settings_welcome_text' %>
|
||||
|
||||
|
||||
<p><%= setting_text_field :per_page_options, :size => 20 %>
|
||||
<em class="info"><%= l(:text_comma_separated) %></em></p>
|
||||
|
||||
<p><%= setting_text_field :search_results_per_page, :size => 6 %>
|
||||
|
||||
<p><%= setting_text_field :activity_days_default, :size => 6 %> <%= l(:label_day_plural) %></p>
|
||||
|
||||
<p><%= setting_text_field :host_name, :size => 60 %>
|
||||
<em class="info"><%= l(:label_example) %>: <%= @guessed_host_and_path %></em></p>
|
||||
|
||||
<p><%= setting_select :protocol, [['HTTP', 'http'], ['HTTPS', 'https']] %></p>
|
||||
|
||||
<p><%= setting_select :text_formatting, Redmine::WikiFormatting.formats_for_select, :blank => :label_none %>
|
||||
<span id="common_mark_info" class="<%= "hidden" unless Setting.text_formatting == "common_mark" %>">
|
||||
<label class="block">
|
||||
<%= check_box_tag(nil, '', Redmine::Configuration['common_mark_enable_hardbreaks'] == true, disabled: true) %>
|
||||
Hardbreaks
|
||||
</label>
|
||||
<em class="info">
|
||||
<%= l(:text_setting_config_change) %>
|
||||
</em>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p><%= setting_check_box :cache_formatted_text %></p>
|
||||
|
||||
<p><%= setting_select :wiki_compression, [['Gzip', 'gzip']], :blank => :label_none %></p>
|
||||
|
||||
<p><%= setting_text_field :feeds_limit, :size => 6 %></p>
|
||||
|
||||
<%= call_hook(:view_settings_general_form) %>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
$('#settings_text_formatting').on('change', function(e){
|
||||
const formatter = e.target.value;
|
||||
const parent_block = document.getElementById("common_mark_info");
|
||||
|
||||
if (formatter == "common_mark") {
|
||||
parent_block.classList.remove('hidden');
|
||||
} else {
|
||||
parent_block.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
<% end %>
|
||||
70
plugins/000_redmine_x_ux_upgrade/app/views/settings/_issues.html.erb
Executable file
70
plugins/000_redmine_x_ux_upgrade/app/views/settings/_issues.html.erb
Executable file
@@ -0,0 +1,70 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'issues'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_check_box :cross_project_issue_relations %></p>
|
||||
|
||||
<p><%= setting_select :link_copied_issue, link_copied_issue_options %></p>
|
||||
|
||||
<p><%= setting_select :cross_project_subtasks, cross_project_subtasks_options %></p>
|
||||
|
||||
<p><%= setting_check_box :close_duplicate_issues %></p>
|
||||
|
||||
<p><%= setting_check_box :issue_group_assignment %></p>
|
||||
|
||||
<p><%= setting_check_box :default_issue_start_date_to_creation_date %></p>
|
||||
|
||||
<p><%= setting_check_box :display_subprojects_issues %></p>
|
||||
|
||||
<p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p>
|
||||
|
||||
<p><%= setting_multiselect :non_working_week_days, (1..7).map {|d| [day_name(d), d.to_s]}, :inline => true %></p>
|
||||
|
||||
<p><%= setting_text_field :issues_export_limit, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_text_field :gantt_items_limit, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_text_field :gantt_months_limit, :size => 6 %></p>
|
||||
</div>
|
||||
|
||||
<fieldset class="box">
|
||||
<legend><%= l(:label_parent_task_attributes) %></legend>
|
||||
<div class="tabular settings">
|
||||
<p><%= setting_select :parent_issue_dates, parent_issue_dates_options, :label => "#{l(:field_start_date)} / #{l(:field_due_date)}" %></p>
|
||||
|
||||
<p><%= setting_select :parent_issue_priority, parent_issue_priority_options, :label => :field_priority %></p>
|
||||
|
||||
<p><%= setting_select :parent_issue_done_ratio, parent_issue_done_ratio_options, :label => :field_done_ratio %></p>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box">
|
||||
<legend><%= l(:setting_issue_list_default_columns) %></legend>
|
||||
<%= render_query_columns_selection(
|
||||
IssueQuery.new(:column_names => Setting.issue_list_default_columns),
|
||||
:name => 'settings[issue_list_default_columns]') %>
|
||||
|
||||
<p><%= setting_multiselect :issue_list_default_totals,
|
||||
IssueQuery.new(:totalable_names => Setting.issue_list_default_totals).available_totalable_columns.map {|c| [c.caption, c.name.to_s]},
|
||||
:inline => true,
|
||||
:label => :label_total_plural %></p>
|
||||
|
||||
<p>
|
||||
<label><%= l(:label_default_query) %></label>
|
||||
<%= setting_select :default_issue_query, default_global_issue_query_options, label: false %>
|
||||
</p>
|
||||
</fieldset>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
48
plugins/000_redmine_x_ux_upgrade/app/views/settings/_mail_handler.html.erb
Executable file
48
plugins/000_redmine_x_ux_upgrade/app/views/settings/_mail_handler.html.erb
Executable file
@@ -0,0 +1,48 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'mail_handler'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p>
|
||||
<%= setting_text_area :mail_handler_body_delimiters, :rows => 5 %>
|
||||
<label class="block">
|
||||
<%= setting_check_box :mail_handler_enable_regex_delimiters, :label => false %>
|
||||
<%= l(:setting_mail_handler_enable_regex) %>
|
||||
</label>
|
||||
<em class="info"><%= l(:text_line_separated) %></em>
|
||||
</p>
|
||||
<p>
|
||||
<%= setting_text_area :mail_handler_excluded_filenames %>
|
||||
<label class="block">
|
||||
<%= setting_check_box :mail_handler_enable_regex_excluded_filenames, :label => false %>
|
||||
<%= l(:setting_mail_handler_enable_regex) %>
|
||||
</label>
|
||||
<em class="info"><%= l(:text_comma_separated) %>
|
||||
<%= l(:label_example) %>: smime.p7s, *.vcf</em>
|
||||
</p>
|
||||
<p><%= setting_select :mail_handler_preferred_body_part, [[l(:label_preferred_body_part_text), 'plain'], [l(:label_preferred_body_part_html), 'html']] %></p>
|
||||
</div>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_check_box :mail_handler_api_enabled,
|
||||
:onclick => "if (this.checked) { $('#settings_mail_handler_api_key').removeAttr('disabled'); } else { $('#settings_mail_handler_api_key').attr('disabled', true); }"%></p>
|
||||
|
||||
<p><%= setting_text_field :mail_handler_api_key, :size => 30,
|
||||
:id => 'settings_mail_handler_api_key',
|
||||
:disabled => !Setting.mail_handler_api_enabled? %>
|
||||
<%= link_to_function l(:label_generate_key), "if (!$('#settings_mail_handler_api_key').attr('disabled')) { $('#settings_mail_handler_api_key').val(randomKey(20)) }" %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,53 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<% if @deliveries %>
|
||||
<%= form_tag({:action => 'edit', :tab => 'notifications'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_text_field :mail_from, :size => 60 %></p>
|
||||
|
||||
<p><%= setting_check_box :plain_text_mail %></p>
|
||||
|
||||
<p><%= setting_check_box :show_status_changes_in_mail_subject %></p>
|
||||
</div>
|
||||
|
||||
<fieldset class="box" id="notified_events"><legend><%=l(:text_select_mail_notifications)%></legend>
|
||||
<%= hidden_field_tag 'settings[notified_events][]', '' %>
|
||||
<% @notifiables.each do |notifiable| %>
|
||||
<%= notification_field notifiable %>
|
||||
<br />
|
||||
<% end %>
|
||||
<p><%= check_all_links('notified_events') %></p>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box"><legend><%= l(:setting_emails_header) %></legend>
|
||||
<%= setting_text_area :emails_header, :label => false, :class => 'wiki-edit', :rows => 5 %>
|
||||
<%= wikitoolbar_for 'settings_emails_header' %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box"><legend><%= l(:setting_emails_footer) %></legend>
|
||||
<%= setting_text_area :emails_footer, :label => false, :class => 'wiki-edit', :rows => 5 %>
|
||||
<%= wikitoolbar_for 'settings_emails_footer' %>
|
||||
</fieldset>
|
||||
|
||||
<div style="float:right;">
|
||||
<%= link_to l(:label_send_test_email), test_email_path, :method => :post %>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="nodata">
|
||||
<%= simple_format(l(:text_email_delivery_not_configured)) %>
|
||||
</div>
|
||||
<% end %>
|
||||
52
plugins/000_redmine_x_ux_upgrade/app/views/settings/_projects.html.erb
Executable file
52
plugins/000_redmine_x_ux_upgrade/app/views/settings/_projects.html.erb
Executable file
@@ -0,0 +1,52 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'projects'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_check_box :default_projects_public %></p>
|
||||
|
||||
<p><%= setting_multiselect(:default_projects_modules,
|
||||
Redmine::AccessControl.available_project_modules.collect {|m| [l_or_humanize(m, :prefix => "project_module_"), m.to_s]}) %></p>
|
||||
|
||||
<p><%= setting_multiselect(:default_projects_tracker_ids,
|
||||
Tracker.sorted.collect {|t| [t.name, t.id.to_s]}) %></p>
|
||||
|
||||
<p><%= setting_check_box :sequential_project_identifiers %></p>
|
||||
|
||||
<p><%= setting_select :new_project_user_role_id,
|
||||
Role.find_all_givable.collect {|r| [r.name, r.id.to_s]},
|
||||
:blank => "--- #{l(:actionview_instancetag_blank_option)} ---" %></p>
|
||||
</div>
|
||||
|
||||
<fieldset class="box">
|
||||
<legend><%= l(:setting_project_list_defaults) %></legend>
|
||||
<% query = ProjectQuery.new(Setting.project_list_defaults) %>
|
||||
<p>
|
||||
<label><%= l(:label_display_type) %></label>
|
||||
<% query.available_display_types.each do |t| %>
|
||||
<%= radio_button_tag('settings[project_list_display_type]', t, Setting.project_list_display_type == t, :id => "setting_project_list_display_type_#{t}") %>
|
||||
<%= content_tag('label', l(:"label_display_type_#{t}"), :for => "settings_project_list_display_type_#{t}", :class => "inline") %>
|
||||
<% end %>
|
||||
</p>
|
||||
<%= render_query_columns_selection(query,
|
||||
:name => 'settings[project_list_defaults][column_names]') %>
|
||||
|
||||
<p>
|
||||
<label><%= l(:label_default_query) %></label>
|
||||
<%= setting_select :default_project_query, default_global_project_query_options, label: false %>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,101 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<fieldset class="box tabular">
|
||||
<legend><%= l(:top_menu_label) %></legend>
|
||||
<p>
|
||||
<label for="settings_show_spent_time_in_top_menu"><%= l(:show_spent_time_in_top_menu) %></label>
|
||||
<span>
|
||||
<span class="floating" style="margin-left: 0px;">
|
||||
<%= check_box_tag 'settings[show_spent_time_in_top_menu]', 1, @settings[:show_spent_time_in_top_menu] %>
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<label for="settings_show_home_page_in_top_menu"><%= l(:show_home_page_in_top_menu) %></label>
|
||||
<span>
|
||||
<span class="floating" style="margin-left: 0px;">
|
||||
<%= check_box_tag 'settings[show_home_page_in_top_menu]', 1, @settings[:show_home_page_in_top_menu] %>
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box tabular">
|
||||
<legend><%= l(:login_redirect_label) %></legend>
|
||||
<p>
|
||||
<label for="settings_redirect_to_my_page"><%= l(:redirect_to_my_page) %></label>
|
||||
<span>
|
||||
<span class="floating" style="margin-left: 0px;">
|
||||
<%= check_box_tag 'settings[redirect_to_my_page]', 1, @settings[:redirect_to_my_page] %>
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box tabular">
|
||||
<legend><%= l(:project_menu_label) %></legend>
|
||||
<p>
|
||||
<label for="settings_number_of_items_in_project_menu"><%= l(:number_of_items_in_project_menu) %></label>
|
||||
<span>
|
||||
<span class="floating" style="margin-left: 0px;">
|
||||
<%= number_field_tag 'settings[number_of_items_in_project_menu]', RedmineXUxUpgradeSetting.number_of_items_in_project_menu, :min => 1 %>
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box tabular">
|
||||
<legend><%= l(:label_issue_plural) %></legend>
|
||||
<p>
|
||||
<label for="settings_remember_collapsed_issues_state"><%= l(:remember_collapsed_issues_state) %></label>
|
||||
<span>
|
||||
<span class="floating" style="margin-left: 0px;">
|
||||
<%= check_box_tag 'settings[remember_collapsed_issues_state]', 1, @settings[:remember_collapsed_issues_state] %>
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box tabular filedroplistner">
|
||||
<legend><%= l(:logo_image_label) %></legend>
|
||||
<p>
|
||||
<div class="redminex-logo-settings">
|
||||
<%= render :partial => 'attachments/form', :locals => {attachment_param: 'logo', :container => @projectino_settings, :multiple => false} %>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<%= link_to l(:remove_logo), delete_attachment_path(@projectino_settings, name: 'logo'), method: :post%>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset class="box tabular filedroplistner">
|
||||
<legend><%= l(:login_images_label) %></legend>
|
||||
<p>
|
||||
<span>
|
||||
<label><b><%= l(:login_desktop_label) %></b></label>
|
||||
</span>
|
||||
<div class="redminex-logo-settings">
|
||||
<%= render :partial => 'attachments/form', :locals => { attachment_param: 'login_desktop', :container => @projectino_settings, :multiple => false} %>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<span>
|
||||
<label><b><%= l(:login_mobile_label) %></b></label>
|
||||
</span>
|
||||
<div class="redminex-logo-settings">
|
||||
<%= render :partial => 'attachments/form', :locals => { attachment_param: 'login_mobile', :container => @projectino_settings, :multiple => false} %>
|
||||
</div>
|
||||
</p>
|
||||
<p>
|
||||
<%= link_to l(:remove_login), delete_attachment_path(@projectino_settings, name: 'login'), method: :post%>
|
||||
</p>
|
||||
</fieldset>
|
||||
<%= hidden_field_tag('settings[version]', Redmine::Plugin.find('000_redmine_x_ux_upgrade').version.delete('.').to_i) %>
|
||||
175
plugins/000_redmine_x_ux_upgrade/app/views/settings/_repositories.html.erb
Executable file
175
plugins/000_redmine_x_ux_upgrade/app/views/settings/_repositories.html.erb
Executable file
@@ -0,0 +1,175 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'repositories'}) do %>
|
||||
|
||||
<fieldset class="box settings enabled_scm">
|
||||
<legend><%= l(:setting_enabled_scm) %></legend>
|
||||
<%= hidden_field_tag 'settings[enabled_scm][]', '' %>
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><%= l(:text_scm_command) %></th>
|
||||
<th><%= l(:text_scm_command_version) %></th>
|
||||
</tr>
|
||||
<% Redmine::Scm::Base.all.collect do |choice| %>
|
||||
<% scm_class = "Repository::#{choice}".constantize %>
|
||||
<% text, value = (choice.is_a?(Array) ? choice : [choice, choice]) %>
|
||||
<% setting = :enabled_scm %>
|
||||
<% enabled = Setting.send(setting).include?(value) %>
|
||||
<tr>
|
||||
<td class="scm_name">
|
||||
<label>
|
||||
<%= check_box_tag("settings[#{setting}][]", value, enabled, :id => nil) %>
|
||||
<%= text.to_s %>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<% if enabled %>
|
||||
<span class="icon <%= (scm_class.scm_available ? 'icon-ok' : 'icon-error') %>"></span>
|
||||
<%= scm_class.scm_command %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<%= scm_class.scm_version_string if enabled %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<p><em class="info"><%= l(:text_scm_config) %></em></p>
|
||||
</fieldset>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_check_box :autofetch_changesets %></p>
|
||||
|
||||
<p><%= setting_check_box :sys_api_enabled,
|
||||
:onclick =>
|
||||
"if (this.checked) { $('#settings_sys_api_key').removeAttr('disabled'); } else { $('#settings_sys_api_key').attr('disabled', true); }" %></p>
|
||||
|
||||
<p><%= setting_text_field :sys_api_key,
|
||||
:size => 30,
|
||||
:id => 'settings_sys_api_key',
|
||||
:disabled => !Setting.sys_api_enabled? %>
|
||||
<%= link_to_function l(:label_generate_key),
|
||||
"if (!$('#settings_sys_api_key').attr('disabled')) { $('#settings_sys_api_key').val(randomKey(20)) }" %>
|
||||
</p>
|
||||
|
||||
<p><%= setting_text_field :repository_log_display_limit, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_check_box :commit_logs_formatting %></p>
|
||||
</div>
|
||||
|
||||
<fieldset class="box tabular settings">
|
||||
<legend><%= l(:text_issues_ref_in_commit_messages) %></legend>
|
||||
<p><%= setting_text_field :commit_ref_keywords, :size => 30 %>
|
||||
<em class="info"><%= l(:text_comma_separated) %></em></p>
|
||||
|
||||
<p><%= setting_check_box :commit_cross_project_ref %></p>
|
||||
|
||||
<p><%= setting_check_box :commit_logtime_enabled,
|
||||
:onclick =>
|
||||
"if (this.checked) { $('#settings_commit_logtime_activity_id').removeAttr('disabled'); } else { $('#settings_commit_logtime_activity_id').attr('disabled', true); }"%></p>
|
||||
|
||||
<p><%= setting_select :commit_logtime_activity_id,
|
||||
[[l(:label_default), 0]] +
|
||||
TimeEntryActivity.shared.active.collect{|activity| [activity.name, activity.id.to_s]},
|
||||
:disabled => !Setting.commit_logtime_enabled?%></p>
|
||||
</fieldset>
|
||||
|
||||
<table class="list" id="commit-keywords">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= l(:label_tracker) %></th>
|
||||
<th><%= l(:setting_commit_fix_keywords) %></th>
|
||||
<th><%= l(:label_applied_status) %></th>
|
||||
<th><%= l(:field_done_ratio) %></th>
|
||||
<th class="buttons"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @commit_update_keywords.each do |rule| %>
|
||||
<tr class="commit-keywords">
|
||||
<td>
|
||||
<%= select_tag(
|
||||
"settings[commit_update_keywords][if_tracker_id][]",
|
||||
options_for_select(
|
||||
[[l(:label_all), ""]] +
|
||||
Tracker.sorted.map {|t| [t.name, t.id.to_s]},
|
||||
rule['if_tracker_id']),
|
||||
:id => nil
|
||||
) %>
|
||||
</td>
|
||||
<td>
|
||||
<%= text_field_tag("settings[commit_update_keywords][keywords][]",
|
||||
rule['keywords'], :id => nil, :size => 30) %>
|
||||
</td>
|
||||
<td>
|
||||
<%= select_tag("settings[commit_update_keywords][status_id][]",
|
||||
options_for_select(
|
||||
[["", 0]] +
|
||||
IssueStatus.sorted.
|
||||
collect{|status| [status.name, status.id.to_s]},
|
||||
rule['status_id']),
|
||||
:id => nil
|
||||
) %>
|
||||
</td>
|
||||
<td>
|
||||
<%= select_tag("settings[commit_update_keywords][done_ratio][]",
|
||||
options_for_select(
|
||||
[["", ""]] +
|
||||
(0..10).to_a.collect {|r| ["#{r*10} %", "#{r*10}"] },
|
||||
rule['done_ratio']),
|
||||
:id => nil
|
||||
) %>
|
||||
</td>
|
||||
<td class="buttons">
|
||||
<%= link_to(l(:button_delete), '#',
|
||||
:class => 'delete-commit-keywords icon-only icon-del',
|
||||
:title => l(:button_delete)) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><em class="info"><%= l(:text_comma_separated) %></em></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="buttons">
|
||||
<%= link_to(l(:button_add), '#',
|
||||
:class => 'add-commit-keywords icon-only icon-add',
|
||||
:title => l(:button_add)) %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
$('#commit-keywords').on('click', 'a.delete-commit-keywords', function(e){
|
||||
e.preventDefault();
|
||||
if ($('#commit-keywords tbody tr.commit-keywords').length > 1) {
|
||||
$(this).parents('#commit-keywords tr').remove();
|
||||
} else {
|
||||
$('#commit-keywords tbody tr.commit-keywords').find('input, select').val('');
|
||||
}
|
||||
});
|
||||
$('#commit-keywords').on('click', 'a.add-commit-keywords', function(e){
|
||||
e.preventDefault();
|
||||
var row = $('#commit-keywords tr.commit-keywords:last');
|
||||
row.clone().insertAfter(row).find('input, select').val('');
|
||||
});
|
||||
<% end %>
|
||||
41
plugins/000_redmine_x_ux_upgrade/app/views/settings/_timelog.html.erb
Executable file
41
plugins/000_redmine_x_ux_upgrade/app/views/settings/_timelog.html.erb
Executable file
@@ -0,0 +1,41 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'timelog'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_multiselect(:timelog_required_fields,
|
||||
[[l(:field_issue), 'issue_id'], [l(:field_comments), 'comments'] ]) %></p>
|
||||
|
||||
<p><%= setting_text_field :timelog_max_hours_per_day, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_check_box :timelog_accept_0_hours %></p>
|
||||
|
||||
<p><%= setting_check_box :timelog_accept_future_dates %></p>
|
||||
</div>
|
||||
|
||||
<fieldset class="box">
|
||||
<legend><%= l(:setting_time_entry_list_defaults) %></legend>
|
||||
|
||||
<% query = TimeEntryQuery.new(Setting.time_entry_list_defaults) %>
|
||||
<%= hidden_field_tag('settings[time_entry_list_defaults][column_names][]', '') %>
|
||||
<%= render_query_columns_selection(query,
|
||||
:name => 'settings[time_entry_list_defaults][column_names]') %>
|
||||
<p>
|
||||
<label><%= l(:label_total_plural) %></label>
|
||||
<%= available_totalable_columns_tags(query,
|
||||
:name => 'settings[time_entry_list_defaults][totalable_names]') %>
|
||||
</p>
|
||||
</fieldset>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
40
plugins/000_redmine_x_ux_upgrade/app/views/settings/_users.html.erb
Executable file
40
plugins/000_redmine_x_ux_upgrade/app/views/settings/_users.html.erb
Executable file
@@ -0,0 +1,40 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({:action => 'edit', :tab => 'users'}) do %>
|
||||
|
||||
<div class="box tabular settings">
|
||||
<p><%= setting_text_field :max_additional_emails, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_text_area :email_domains_allowed %>
|
||||
<em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: example.com, example.org</em></p>
|
||||
|
||||
<p><%= setting_text_area :email_domains_denied %>
|
||||
<em class="info"><%= l(:text_comma_separated) %> <%= l(:label_example) %>: .example.com, foo.example.org, example.net</em></p>
|
||||
|
||||
<p><%= setting_check_box :unsubscribe %></p>
|
||||
</div>
|
||||
|
||||
<fieldset class="box tabular settings">
|
||||
<legend><%= l(:label_default_values_for_new_users) %></legend>
|
||||
|
||||
<p><%= setting_check_box :default_users_hide_mail, :label => :field_hide_mail %></p>
|
||||
|
||||
<p><%= setting_select(:default_notification_option, User.valid_notification_options.collect {|o| [l(o.last), o.first.to_s]}) %></p>
|
||||
|
||||
<p><%= setting_check_box :default_users_no_self_notified, :label => :label_user_mail_no_self_notified %></p>
|
||||
|
||||
<p><%= setting_select :default_users_time_zone, ActiveSupport::TimeZone.all.collect {|z| [ z.to_s, z.name ]}, :label => :field_time_zone, :blank => :label_none %></p>
|
||||
</fieldset>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
24
plugins/000_redmine_x_ux_upgrade/app/views/settings/plugin.html.erb
Executable file
24
plugins/000_redmine_x_ux_upgrade/app/views/settings/plugin.html.erb
Executable file
@@ -0,0 +1,24 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_plugins), {:controller => 'admin', :action => 'plugins'}], @plugin.name %>
|
||||
|
||||
<div id="settings" class="plugin plugin-<%= @plugin.id %>">
|
||||
<%= form_tag({:action => 'plugin'}) do %>
|
||||
|
||||
<%= render :partial => @partial, :locals => {:settings => @settings}%>
|
||||
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_apply) %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -0,0 +1,94 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= error_messages_for 'time_entry' %>
|
||||
<%= back_url_hidden_field_tag %>
|
||||
|
||||
<div class="box tabular">
|
||||
<!-- CHANGE Project drop down is now always visible, is user is in the project, this project is preselected -->
|
||||
<p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).to_a, :selected => @time_entry.project, :include_blank => true), :required => true %></p>
|
||||
|
||||
<p>
|
||||
<%= f.text_field :issue_id, :size => 6, :required => Setting.timelog_required_fields.include?('issue_id') %>
|
||||
<span id="time_entry_issue">
|
||||
<%= link_to_issue(@time_entry.issue) if @time_entry.issue.try(:visible?) %>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<% if User.current.allowed_to?(:log_time_for_other_users, @project) %>
|
||||
<p><%= f.select :user_id, user_collection_for_select_options(@time_entry), :required => true %></p>
|
||||
<% elsif !@time_entry.new_record? %>
|
||||
<p>
|
||||
<%= f.label_for_field :user_id %>
|
||||
<span><%= link_to_user(@time_entry.user) %></span>
|
||||
</p>
|
||||
<% end %>
|
||||
<p><%= f.date_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
|
||||
<p><%= f.hours_field :hours, :size => 6, :required => true %></p>
|
||||
<p><%= f.text_field :comments, :size => 100, :maxlength => 1024, :required => Setting.timelog_required_fields.include?('comments') %></p>
|
||||
<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
|
||||
<% @time_entry.editable_custom_field_values.each do |value| %>
|
||||
<p><%= custom_field_tag_with_label :time_entry, value %></p>
|
||||
<% if value.custom_field.full_text_formatting? %>
|
||||
<%= wikitoolbar_for "time_entry_custom_field_values_#{value.custom_field_id}", preview_issue_path(:project_id => @project) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
|
||||
</div>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
$(document).ready(function(){
|
||||
$('#time_entry_project_id').change(function(){
|
||||
$('#time_entry_issue_id').val('');
|
||||
});
|
||||
$('#time_entry_project_id, #time_entry_issue_id').change(function(){
|
||||
$.ajax({
|
||||
url: '<%= escape_javascript(@time_entry.new_record? ? new_time_entry_path(:format => 'js') : edit_time_entry_path(:format => 'js')) %>',
|
||||
type: 'post',
|
||||
data: $(this).closest('form').serialize()
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
observeAutocompleteField('time_entry_issue_id',
|
||||
function(request, callback) {
|
||||
var url = '<%= j auto_complete_issues_path %>';
|
||||
var data = {
|
||||
term: request.term
|
||||
};
|
||||
var project_id;
|
||||
<% if @time_entry.new_record? && @project %>
|
||||
project_id = '<%= @project.id %>';
|
||||
<% else %>
|
||||
project_id = $('#time_entry_project_id').val();
|
||||
<% end %>
|
||||
if(project_id){
|
||||
data['project_id'] = project_id;
|
||||
} else {
|
||||
data['scope'] = 'all';
|
||||
}
|
||||
|
||||
$.get(url, data, null, 'json')
|
||||
.done(function(data){
|
||||
callback(data);
|
||||
})
|
||||
.fail(function(jqXHR, status, error){
|
||||
callback([]);
|
||||
});
|
||||
},
|
||||
{
|
||||
select: function(event, ui) {
|
||||
$('#time_entry_issue').text('');
|
||||
$('#time_entry_issue_id').val(ui.item.value).change();
|
||||
}
|
||||
}
|
||||
);
|
||||
<% end %>
|
||||
20
plugins/000_redmine_x_ux_upgrade/app/views/timelog/edit.html.erb
Executable file
20
plugins/000_redmine_x_ux_upgrade/app/views/timelog/edit.html.erb
Executable file
@@ -0,0 +1,20 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%= l(:label_spent_time) %></h2>
|
||||
|
||||
<%= labelled_form_for @time_entry, :url => time_entry_path(@time_entry), :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<%= cancel_button_tag_for_time_entry(@project) %>
|
||||
</div>
|
||||
<% end %>
|
||||
21
plugins/000_redmine_x_ux_upgrade/app/views/timelog/new.html.erb
Executable file
21
plugins/000_redmine_x_ux_upgrade/app/views/timelog/new.html.erb
Executable file
@@ -0,0 +1,21 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<h2><%= l(:label_spent_time) %></h2>
|
||||
|
||||
<%= labelled_form_for @time_entry, :url => time_entries_path, :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => {:f => f} %>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
|
||||
<%= cancel_button_tag_for_time_entry(@project) %>
|
||||
</div>
|
||||
<% end %>
|
||||
73
plugins/000_redmine_x_ux_upgrade/app/views/trackers/_form.html.erb
Executable file
73
plugins/000_redmine_x_ux_upgrade/app/views/trackers/_form.html.erb
Executable file
@@ -0,0 +1,73 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= error_messages_for 'tracker' %>
|
||||
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<div class="box tabular">
|
||||
<!--[form:tracker]-->
|
||||
<p><%= f.text_field :name, :required => true %></p>
|
||||
<p><%= f.select :default_status_id,
|
||||
IssueStatus.sorted.map {|s| [s.name, s.id]},
|
||||
:include_blank => @tracker.default_status.nil?,
|
||||
:required => true %>
|
||||
</p>
|
||||
<p><%= f.check_box :is_in_roadmap %></p>
|
||||
<p><%= f.text_area :description, :rows => 4 %></p>
|
||||
<p>
|
||||
<label><%= l(:field_core_fields) %></label>
|
||||
<% Tracker::CORE_FIELDS.each do |field| %>
|
||||
<label class="block">
|
||||
<%= check_box_tag 'tracker[core_fields][]', field, @tracker.core_fields.include?(field), :id => nil %>
|
||||
<%= l("field_#{field}".sub(/_id$/, '')) %>
|
||||
</label>
|
||||
<% end %>
|
||||
</p>
|
||||
<%= hidden_field_tag 'tracker[core_fields][]', '' %>
|
||||
|
||||
<% @issue_custom_fields = IssueCustomField.sorted %>
|
||||
<% if @issue_custom_fields.present? %>
|
||||
<p>
|
||||
<label><%= l(:label_custom_field_plural) %></label>
|
||||
<% @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 %>
|
||||
</label>
|
||||
<% end %>
|
||||
</p>
|
||||
<%= hidden_field_tag 'tracker[custom_field_ids][]', '' %>
|
||||
<% end %>
|
||||
|
||||
<% if @tracker.new_record? && @trackers.any? %>
|
||||
<p><label for="copy_workflow_from"><%= l(:label_copy_workflow_from) %></label>
|
||||
<%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@trackers, :id, :name, params[:copy_workflow_from] || @copy_from.try(:id))) %></p>
|
||||
<% end %>
|
||||
<!--[eoform:tracker]-->
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(@tracker.new_record? ? :button_create : :button_save) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="splitcontentright">
|
||||
<% if @projects.any? %>
|
||||
<fieldset class="box" id="tracker_project_ids"><legend><%= toggle_checkboxes_link("#tracker_project_ids input[type=checkbox]") %><%= l(:label_project_plural) %></legend>
|
||||
<% project_ids = @tracker.project_ids.to_a %>
|
||||
<%= render_project_nested_lists(@projects) do |p|
|
||||
content_tag('label', check_box_tag('tracker[project_ids][]', p.id, project_ids.include?(p.id), :id => nil) + ' ' + h(p))
|
||||
end %>
|
||||
<%= hidden_field_tag('tracker[project_ids][]', '', :id => nil) %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,92 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_tracker_plural), trackers_path], l(:field_summary) %>
|
||||
|
||||
<% if @trackers.any? %>
|
||||
<%= form_tag fields_trackers_path do %>
|
||||
<div class="autoscroll">
|
||||
<table class="list tracker-summary">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<% @trackers.each do |tracker| %>
|
||||
<th>
|
||||
<%= link_to_function('', "toggleCheckboxesBySelector('input.tracker-#{tracker.id}')",
|
||||
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
|
||||
:class => 'icon-only icon-checked') %>
|
||||
<%= tracker.name %>
|
||||
</th>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="group open">
|
||||
<td colspan="<%= @trackers.size + 1 %>">
|
||||
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
||||
<%= l(:field_core_fields) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% Tracker::CORE_FIELDS.each do |field| %>
|
||||
<tr>
|
||||
<% field_name = l("field_#{field}".sub(/_id$/, '')) %>
|
||||
<td class="name">
|
||||
<%= link_to_function('', "toggleCheckboxesBySelector('input.core-field-#{field}')",
|
||||
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
|
||||
:class => 'icon-only icon-checked') %>
|
||||
<%= field_name %>
|
||||
</td>
|
||||
<% @trackers.each do |tracker| %>
|
||||
<td title="<%= "#{tracker.name}: #{field_name}" %>">
|
||||
<%= check_box_tag "trackers[#{tracker.id}][core_fields][]", field, tracker.core_fields.include?(field),
|
||||
:class => "tracker-#{tracker.id} core-field-#{field}", :id => nil %>
|
||||
</td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% if @custom_fields.any? %>
|
||||
<tr class="group open">
|
||||
<td colspan="<%= @trackers.size + 1 %>">
|
||||
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
||||
<%= l(:label_custom_field_plural) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% @custom_fields.each do |field| %>
|
||||
<tr>
|
||||
<td class="name">
|
||||
<%= link_to_function('', "toggleCheckboxesBySelector('input.custom-field-#{field.id}')",
|
||||
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
|
||||
:class => 'icon-only icon-checked') %>
|
||||
<%= field.name %>
|
||||
</td>
|
||||
<% @trackers.each do |tracker| %>
|
||||
<td title="<%= "#{tracker.name}: #{field.name}" %>">
|
||||
<%= check_box_tag "trackers[#{tracker.id}][custom_field_ids][]", field.id, tracker.custom_fields.include?(field),
|
||||
:class => "tracker-#{tracker.id} custom-field-#{field.id}", :id => nil %>
|
||||
</td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<p><%= submit_tag l(:button_save) %></p>
|
||||
</div>
|
||||
<% @trackers.each do |tracker| %>
|
||||
<%= hidden_field_tag "trackers[#{tracker.id}][core_fields][]", '' %>
|
||||
<%= hidden_field_tag "trackers[#{tracker.id}][custom_field_ids][]", '' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||
<% end %>
|
||||
@@ -0,0 +1,18 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= labelled_form_for @user, :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<% if @user.active? && email_delivery_enabled? && @user != User.current -%>
|
||||
<p><label><%= check_box_tag 'send_information', 1, params[:send_information] %> <%= l(:label_send_information) %></label></p>
|
||||
<% end -%>
|
||||
<div class="projectino-controls"><%= submit_tag l(:button_save) %></div>
|
||||
<% end %>
|
||||
@@ -0,0 +1,24 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_for(:user, :url => { :action => 'update' }, :html => {:method => :put}) do %>
|
||||
<div class="box">
|
||||
<div id="user_group_ids">
|
||||
<% user_group_ids = @user.group_ids %>
|
||||
<% Group.givable.sort.each do |group| %>
|
||||
<label><%= check_box_tag 'user[group_ids][]', group.id, user_group_ids.include?(group.id), :id => nil %> <%= group %></label><br />
|
||||
<% end %>
|
||||
<%= hidden_field_tag 'user[group_ids][]', '' %>
|
||||
</div>
|
||||
<p><%= check_all_links 'user_group_ids' %></p>
|
||||
</div>
|
||||
<div class="projectino-controls"><%= submit_tag l(:button_save) %></div>
|
||||
<% end %>
|
||||
43
plugins/000_redmine_x_ux_upgrade/app/views/users/new.html.erb
Executable file
43
plugins/000_redmine_x_ux_upgrade/app/views/users/new.html.erb
Executable file
@@ -0,0 +1,43 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= title [l(:label_user_plural), users_path], l(:label_user_new) %>
|
||||
|
||||
<%= labelled_form_for @user, :html => {:multipart => true} do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<% if email_delivery_enabled? %>
|
||||
<p><label><%= check_box_tag 'send_information', 1, params[:send_information] %> <%= l(:label_send_information) %></label></p>
|
||||
<% end %>
|
||||
<p>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
|
||||
</div>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @auth_sources.present? && @auth_sources.any?(&:searchable?) %>
|
||||
<%= javascript_tag do %>
|
||||
observeAutocompleteField('user_login', '<%= escape_javascript autocomplete_for_new_user_auth_sources_path %>', {
|
||||
select: function(event, ui) {
|
||||
$('input#user_firstname').val(ui.item.firstname);
|
||||
$('input#user_lastname').val(ui.item.lastname);
|
||||
$('input#user_mail').val(ui.item.mail);
|
||||
$('select#user_auth_source_id option').each(function(){
|
||||
if ($(this).attr('value') == ui.item.auth_source_id) {
|
||||
$(this).prop('selected', true);
|
||||
$('select#user_auth_source_id').trigger('change');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
<% end %>
|
||||
<% end %>
|
||||
67
plugins/000_redmine_x_ux_upgrade/app/views/versions/_sidebar.html.erb
Executable file
67
plugins/000_redmine_x_ux_upgrade/app/views/versions/_sidebar.html.erb
Executable file
@@ -0,0 +1,67 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= form_tag({}, :method => :get) do %>
|
||||
<%= hidden_field_tag "tracker_ids[]", nil, :id => nil %>
|
||||
<h3><%= l(:label_roadmap) %></h3>
|
||||
<ul>
|
||||
<% @trackers.each do |tracker| %>
|
||||
<li>
|
||||
<label>
|
||||
<%= check_box_tag("tracker_ids[]", tracker.id,
|
||||
(@selected_tracker_ids.include? tracker.id.to_s),
|
||||
:id => nil) %>
|
||||
<%= tracker.name %>
|
||||
</label>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<p></p>
|
||||
<ul>
|
||||
<li>
|
||||
<label for="completed">
|
||||
<%= check_box_tag "completed", 1, params[:completed] %> <%= l(:label_show_completed_versions) %>
|
||||
</label>
|
||||
</li>
|
||||
<% if @project.descendants.active.any? %>
|
||||
<li>
|
||||
<%= hidden_field_tag 'with_subprojects', 0, :id => nil %>
|
||||
<label>
|
||||
<%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%>
|
||||
</label>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @versions.any? %>
|
||||
<h3><%= l(:label_version_plural) %></h3>
|
||||
<% end %>
|
||||
<ul>
|
||||
<% @versions.each do |version| %>
|
||||
<li>
|
||||
<%= link_to(format_version_name(version), "##{version_anchor(version)}") %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% if @completed_versions.present? %>
|
||||
<p>
|
||||
<%= link_to_function l(:label_completed_versions),
|
||||
'$("#toggle-completed-versions").toggleClass("icon-collapsed icon-expanded"); $("#completed-versions").toggle()',
|
||||
:id => 'toggle-completed-versions', :class => 'icon icon-collapsed collapsible' %>
|
||||
<ul id = "completed-versions" style = "display:none;">
|
||||
<% @completed_versions.each do |version| %>
|
||||
<li><%= link_to_version version %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</p>
|
||||
<% end %>
|
||||
@@ -0,0 +1,72 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<div class="contextual">
|
||||
<%= link_to(l(:button_edit), edit_version_path(@version), :class => 'icon icon-edit') if User.current.allowed_to?(:manage_versions, @version.project) %>
|
||||
<%= link_to_if_authorized(l(:button_edit_associated_wikipage, :page_title => @version.wiki_page_title), {:controller => 'wiki', :action => 'edit', :project_id => @version.project, :id => Wiki.titleize(@version.wiki_page_title)}, :class => 'icon icon-edit') unless @version.wiki_page_title.blank? || @version.project.wiki.nil? %>
|
||||
<%= delete_link version_path(@version, :back_url => url_for(:controller => 'versions', :action => 'index', :project_id => @version.project)) if User.current.allowed_to?(:manage_versions, @version.project) %>
|
||||
<%= link_to_new_issue(@version, @project) %>
|
||||
<%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %>
|
||||
</div>
|
||||
|
||||
<div id="roadmap" class="<%= @version.css_classes %>">
|
||||
<h2 class="inline-flex"><%= @version.name %></h2>
|
||||
<span class="badge badge-status-<%= @version.status %>"><%= l("version_status_#{@version.status}") %></span>
|
||||
|
||||
<%= render :partial => 'versions/overview', :locals => {:version => @version} %>
|
||||
<%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
|
||||
|
||||
<div id="version-summary">
|
||||
<% if @version.visible_fixed_issues.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
|
||||
<fieldset class="time-tracking"><legend><%= l(:label_time_tracking) %></legend>
|
||||
<table>
|
||||
<tr>
|
||||
<th><%= l(:field_estimated_hours) %></th>
|
||||
<td class="total-hours"><%= link_to html_hours(l_hours(@version.visible_fixed_issues.estimated_hours)),
|
||||
project_issues_path(@version.project, :set_filter => 1, :status_id => '*', :fixed_version_id => @version.id, :c => [:tracker, :status, :subject, :estimated_hours], :t => [:estimated_hours]) %></td>
|
||||
</tr>
|
||||
<% if User.current.allowed_to_view_all_time_entries?(@project) %>
|
||||
<tr>
|
||||
<th><%= l(:label_spent_time) %></th>
|
||||
<td class="total-hours"><%= link_to html_hours(l_hours(@version.spent_hours)),
|
||||
project_time_entries_path(@version.project, :set_filter => 1, :"issue.fixed_version_id" => @version.id) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
<div id="status_by">
|
||||
<%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.exists? %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if @issues.present? %>
|
||||
<%= form_tag({}, :data => {:cm_url => issues_context_menu_path}) do -%>
|
||||
<table class="list related-issues">
|
||||
<caption><%= l(:label_related_issues) %></caption>
|
||||
<%- @issues.each do |issue| -%>
|
||||
<tr class="hascontextmenu <%= issue.css_classes %>">
|
||||
<td class="checkbox"><%= check_box_tag 'ids[]', issue.id, false, :id => nil %></td>
|
||||
<td class="assigned_to"><%= assignee_avatar(issue.assigned_to, :size => 16) %></td>
|
||||
<td class="subject"><%= link_to_issue(issue, :project => (@project != issue.project)) %></td>
|
||||
<td class="buttons"><%= link_to_context_menu_with_edit(issue) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
<%= context_menu %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= call_hook :view_versions_show_bottom, :version => @version %>
|
||||
|
||||
<% html_title @version.name %>
|
||||
@@ -0,0 +1,88 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= wiki_page_breadcrumb(@page) %>
|
||||
|
||||
<h2><%= @page.pretty_title %></h2>
|
||||
|
||||
<%= form_for @content, :as => :content,
|
||||
:url => {:action => 'update', :id => @page.title},
|
||||
:html => {:method => :put, :multipart => true, :id => 'wiki_form'} do |f| %>
|
||||
<%= f.hidden_field :version %>
|
||||
<% if @section %>
|
||||
<%= hidden_field_tag 'section', @section %>
|
||||
<%= hidden_field_tag 'section_hash', @section_hash %>
|
||||
<% end %>
|
||||
<%= error_messages_for 'content' %>
|
||||
|
||||
<div class="box tabular">
|
||||
<%= text_area_tag 'content[text]', @text, :cols => 100, :rows => 25, :accesskey => accesskey(:edit),
|
||||
:class => 'wiki-edit',
|
||||
:data => {
|
||||
:auto_complete => true
|
||||
}
|
||||
%>
|
||||
|
||||
<% if @page.safe_attribute_names.include?('parent_id') && @wiki.pages.any? %>
|
||||
<%= fields_for @page do |fp| %>
|
||||
<p>
|
||||
<label><%= l(:field_parent_title) %></label>
|
||||
<%= fp.select :parent_id,
|
||||
content_tag('option', '', :value => '') +
|
||||
wiki_page_options_for_select(
|
||||
@wiki.pages.includes(:parent).to_a -
|
||||
@page.self_and_descendants, @page.parent) %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<p><label><%= l(:field_comments) %></label><%= f.text_field :comments, :size => 120, :maxlength => 1024 %></p>
|
||||
<fieldset>
|
||||
<legend><%=l(:label_attachment_plural)%></legend>
|
||||
<% if @page.attachments.any? && @page.safe_attribute?('deleted_attachment_ids') %>
|
||||
<div class="contextual"><%= link_to l(:label_edit_attachments), '#', :onclick => "$('#existing-attachments').toggle(); return false;" %></div>
|
||||
<div id="existing-attachments" style="<%= @page.deleted_attachment_ids.blank? ? 'display:none;' : '' %>">
|
||||
<% @page.attachments.each do |attachment| %>
|
||||
<span class="existing-attachment">
|
||||
<%= text_field_tag '', attachment.filename, :class => "icon icon-attachment filename", :disabled => true %>
|
||||
<label class='inline'>
|
||||
<%= check_box_tag 'wiki_page[deleted_attachment_ids][]',
|
||||
attachment.id,
|
||||
@page.deleted_attachment_ids.include?(attachment.id),
|
||||
:id => nil, :class => "deleted_attachment" %> <%= l(:button_delete) %>
|
||||
</label>
|
||||
</span>
|
||||
<% end %>
|
||||
<hr />
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="new-attachments" style="display:inline-block;">
|
||||
<%= render :partial => 'attachments/form' %>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<%= link_to l(:button_cancel), wiki_page_edit_cancel_path(@page) %>
|
||||
</div>
|
||||
<%= wikitoolbar_for 'content_text', preview_project_wiki_page_path(:project_id => @project, :id => @page.title) %>
|
||||
|
||||
<% if User.current.allowed_to?(:add_wiki_page_watchers, @project)%>
|
||||
<%= update_data_sources_for_auto_complete({users: watchers_autocomplete_for_mention_path(project_id: @project, q: '', object_type: 'wiki_page', object_id: @page.id)}) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= robot_exclusion_tag %>
|
||||
<% end %>
|
||||
|
||||
<% html_title @page.pretty_title %>
|
||||
73
plugins/000_redmine_x_ux_upgrade/app/views/workflows/edit.html.erb
Executable file
73
plugins/000_redmine_x_ux_upgrade/app/views/workflows/edit.html.erb
Executable file
@@ -0,0 +1,73 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= render :partial => 'action_menu' %>
|
||||
|
||||
<%= title l(:label_workflow) %>
|
||||
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li><%= link_to l(:label_status_transitions), edit_workflows_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
|
||||
<li><%= link_to l(:label_fields_permissions), permissions_workflows_path(:role_id => @roles, :tracker_id => @trackers) %></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p><%=l(:text_workflow_edit)%>:</p>
|
||||
|
||||
<%= form_tag({}, :method => 'get') do %>
|
||||
<p>
|
||||
<label><%=l(:label_role)%>:
|
||||
<%= options_for_workflow_select 'role_id[]', Role.sorted.select(&:consider_workflow?), @roles, :id => 'role_id', :class => 'expandable' %>
|
||||
<span class="toggle-multiselect icon-only"></span>
|
||||
</label>
|
||||
|
||||
<label><%=l(:label_tracker)%>:
|
||||
<%= options_for_workflow_select 'tracker_id[]', Tracker.sorted, @trackers, :id => 'tracker_id', :class => 'expandable' %>
|
||||
<span class="toggle-multiselect icon-only"></span>
|
||||
</label>
|
||||
|
||||
<%= submit_tag l(:button_edit), :name => nil %>
|
||||
|
||||
<%= hidden_field_tag 'used_statuses_only', '0', :id => nil %>
|
||||
<label><%= check_box_tag 'used_statuses_only', '1', @used_statuses_only %> <%= l(:label_display_used_statuses_only) %></label>
|
||||
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @trackers && @roles && @statuses.any? %>
|
||||
<%= form_tag workflows_path, method: :patch, id: 'workflow_form' do %>
|
||||
<%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id, :id => nil}.join.html_safe %>
|
||||
<%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id, :id => nil}.join.html_safe %>
|
||||
<%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only], :id => nil %>
|
||||
<div class="autoscroll">
|
||||
<%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %>
|
||||
|
||||
<fieldset class="collapsible" style="padding: 0; margin-top: 0.5em;">
|
||||
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_author) %></legend>
|
||||
<div id="author_workflows" style="margin: 0.5em 0 0.5em 0;">
|
||||
<%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<%= javascript_tag "hideFieldset($('#author_workflows'))" unless @workflows['author'].present? %>
|
||||
|
||||
<fieldset class="collapsible" style="padding: 0;">
|
||||
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_assignee) %></legend>
|
||||
<div id="assignee_workflows" style="margin: 0.5em 0 0.5em 0;">
|
||||
<%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<%= javascript_tag "hideFieldset($('#assignee_workflows'))" unless @workflows['assignee'].present? %>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,123 @@
|
||||
<%#
|
||||
This file is a part of RedmineX UX Upgrade plugin
|
||||
for Redmine
|
||||
|
||||
Copyright 2020-2022 RedmineX. All Rights Reserved.
|
||||
https://www.redmine-x.com
|
||||
|
||||
Licensed under GPL v2 (http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
Created by Ondřej Svejkovský
|
||||
%>
|
||||
|
||||
<%= render :partial => 'action_menu' %>
|
||||
|
||||
<%= title l(:label_workflow) %>
|
||||
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li><%= link_to l(:label_status_transitions), edit_workflows_path(:role_id => @roles, :tracker_id => @trackers) %></li>
|
||||
<li><%= link_to l(:label_fields_permissions), permissions_workflows_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p><%=l(:text_workflow_edit)%>:</p>
|
||||
|
||||
<%= form_tag({}, :method => 'get') do %>
|
||||
<p>
|
||||
<label><%=l(:label_role)%>:
|
||||
<%= options_for_workflow_select 'role_id[]', Role.sorted.select(&:consider_workflow?), @roles, :id => 'role_id', :class => 'expandable' %>
|
||||
<span class="toggle-multiselect icon-only"></span>
|
||||
</label>
|
||||
|
||||
<label><%=l(:label_tracker)%>:
|
||||
<%= options_for_workflow_select 'tracker_id[]', Tracker.sorted, @trackers, :id => 'tracker_id', :class => 'expandable' %>
|
||||
<span class="toggle-multiselect icon-only"></span>
|
||||
</label>
|
||||
|
||||
<%= submit_tag l(:button_edit), :name => nil %>
|
||||
|
||||
<%= hidden_field_tag 'used_statuses_only', '0', :id => nil %>
|
||||
<label><%= check_box_tag 'used_statuses_only', '1', @used_statuses_only %> <%= l(:label_display_used_statuses_only) %></label>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @trackers && @roles && @statuses.any? %>
|
||||
<%= form_tag update_permissions_workflows_path, method: :patch, id: 'workflow_form' do %>
|
||||
<%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id, :id => nil}.join.html_safe %>
|
||||
<%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id, :id => nil}.join.html_safe %>
|
||||
<%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only], :id => nil %>
|
||||
<div class="autoscroll">
|
||||
<table class="list workflows fields_permissions">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
</th>
|
||||
<th colspan="<%= @statuses.length %>"><%=l(:label_issue_status)%></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<% for status in @statuses %>
|
||||
<td style="width:<%= 75 / @statuses.size %>%;">
|
||||
<%= status.name %>
|
||||
</td>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="group open">
|
||||
<td colspan="<%= @statuses.size + 1 %>">
|
||||
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
||||
<%= l(:field_core_fields) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% @fields.each do |field, name| %>
|
||||
<tr>
|
||||
<td class="name">
|
||||
<%= name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %>
|
||||
</td>
|
||||
<% for status in @statuses -%>
|
||||
<td class="<%= @permissions[status.id][field].try(:join, ' ') %>" title="<%= name %> (<%= status.name %>)">
|
||||
<%= field_permission_tag(@permissions, status, field, @roles) %>
|
||||
<% unless status == @statuses.last %><a href="#" class="repeat-value" title="<%= l(:button_copy) %>">»</a><% end %>
|
||||
</td>
|
||||
<% end -%>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% if @custom_fields.any? %>
|
||||
<tr class="group open">
|
||||
<td colspan="<%= @statuses.size + 1 %>">
|
||||
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
||||
<%= l(:label_custom_field_plural) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% @custom_fields.each do |field| %>
|
||||
<tr>
|
||||
<td class="name">
|
||||
<%= field.name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %>
|
||||
</td>
|
||||
<% for status in @statuses -%>
|
||||
<td class="<%= @permissions[status.id][field.id.to_s].try(:join, ' ') %>" title="<%= field.name %> (<%= status.name %>)">
|
||||
<%= field_permission_tag(@permissions, status, field, @roles) %>
|
||||
<% unless status == @statuses.last %><a href="#" class="repeat-value">»</a><% end %>
|
||||
</td>
|
||||
<% end -%>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="projectino-controls">
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
$("a.repeat-value").click(function(e){
|
||||
e.preventDefault();
|
||||
var td = $(this).closest('td');
|
||||
var selected = td.find("select").find(":selected").val();
|
||||
td.nextAll('td').find("select").val(selected);
|
||||
});
|
||||
<% end %>
|
||||
11
plugins/000_redmine_x_ux_upgrade/assets/javascripts/redmine_x_ux_upgrade.min.js
vendored
Normal file
11
plugins/000_redmine_x_ux_upgrade/assets/javascripts/redmine_x_ux_upgrade.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
plugins/000_redmine_x_ux_upgrade/assets/javascripts/select2.min.js
vendored
Executable file
2
plugins/000_redmine_x_ux_upgrade/assets/javascripts/select2.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
1
plugins/000_redmine_x_ux_upgrade/assets/stylesheets/blank.css
Executable file
1
plugins/000_redmine_x_ux_upgrade/assets/stylesheets/blank.css
Executable file
@@ -0,0 +1 @@
|
||||
/* Blank file, used for blocking redmine's default styles */
|
||||
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Projectino
|
||||
* Copyright 2020 RedmineX
|
||||
* For license, see https://www.redmine-x.com
|
||||
* Created by Michael Staněk
|
||||
* Created without vendor prefixes, "AutoPrefixed" by PrePros v5 (https://prepros.io)
|
||||
*/.controller-my.action-page #header>h1,#footer,.controller-account.action-login #top-menu,.controller-account.action-login #header,#quick-search label[for="q"],.controller-issues.action-show #content>h2:first-of-type,.next-prev-links.contextual,.journal .journal-link{display:none !important}body:not([class*="project-"]) #main-menu,body:not([class*="project-"]) #main-menu2{display:none !important}body:not([class*="project-"]) #header{padding:0}@media only screen and (min-width: 899px){body:not([class*="project-"]) #header>h1{display:none !important}}@media only screen and (max-width: 899px){.controller-my.action-page #content>.contextual{display:none}}@media only screen and (max-width: 899px){.controller-my.action-page .contextual .icon-sort-handle,.controller-my.action-page .contextual .icon-settings,.controller-my.action-page .contextual .icon-close{display:none}}.controller-my.action-page #block-starting_with_projectino iframe{width:100% !important}.controller-issues.action-show .issue .subject>div>p{display:none !important}.controller-issues.action-show #wrapper #content>.contextual{margin-bottom:0.5rem !important}@media only screen and (min-width: 1200px){.controller-issues.action-show #wrapper #content>.contextual{margin-top:1rem !important}}#main-menu #new-object,#main-menu2 #new-object{display:none}.controller-versions #content>.contextual>.drdn{display:none}.controller-agile_boards.action-index #sidebar>h3:first-of-type,.controller-agile_boards.action-index #sidebar>ul:first-of-type{display:none}.controller-projects.action-show .box.spent_time{display:none !important}.controller-projects.action-show .splitcontentright{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}#chat-application{max-height:600px;max-width:366px;height:calc(100vh - 36px);width:366px;display:none !important}@media only screen and (min-width: 899px){#chat-application.d-block{display:block !important}}table.list.issues .id{display:none !important}#tab-content-display .box.tabular.settings p:first-child{display:none !important}#admin-menu li:nth-last-child(-n+2){display:none !important}.starting-block-box{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}@media only screen and (min-width: 768px){.starting-block-box{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}}.starting-block-video{-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%}@media only screen and (min-width: 768px){.starting-block-video{-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%}}@media only screen and (min-width: 1200px){.starting-block-video{-webkit-flex:0 0 33%;-ms-flex:0 0 33%;flex:0 0 33%}}.starting-block-text{-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;padding:0 2rem}@media only screen and (min-width: 768px){.starting-block-text{-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%}}@media only screen and (min-width: 1200px){.starting-block-text{-webkit-flex:0 0 66%;-ms-flex:0 0 66%;flex:0 0 66%}}.starting-block-text ul{margin-bottom:1rem}.starting-block-text .gravatar{float:left;margin-right:0.5rem}.controller-settings.action-plugin #content>h2{display:none}body:not([class*="project-"]).controller-redmine_x_gantt #content,body:not([class*="project-"]).controller-redmine_x_resources #content{padding-top:1rem !important}.controller-account.action-login:after{content:'Projectino je vyrobeno s ❤ v Praze';position:absolute;top:20%;right:2.5%;color:#fff;font-weight:500;max-width:200px;text-align:right}@media only screen and (min-width: 899px){.controller-account.action-login:after{max-width:300px;font-size:1.25rem;top:8%}}
|
||||
|
||||
/*# sourceMappingURL=extension-projectino.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../themes/redminex_theme/stylesheets/scss/extension-projectino.scss","../themes/redminex_theme/stylesheets/themes/redminex_theme/stylesheets/scss/extension-projectino.scss"],"names":[],"mappings":"AAAA;;;;;;GCMG,2QAUC,uBAAyB,CAC5B,mFAoCO,uBAAyB,CAlCjC,sCAsCQ,SAAW,CAGP,0CAzCZ,yCA0CgB,uBAAyB,CAEhC,CAOD,0CAHR,gDAIY,YAAc,CAErB,CAOO,0CAbZ,kKAcgB,YAAc,CAErB,CAhBT,kEAoBQ,qBAAuB,CAC1B,qDAQO,uBAAyB,CALrC,6DAUG,+BAAiC,CAE3B,2CAZT,6DAaY,0BAA4B,CAErC,CAGH,+CAIQ,YAAc,CACjB,gDAMG,YAAc,CACjB,gIAWW,YAAc,CACjB,iDASD,uBAAyB,CAJrC,oDASQ,qBACA,AADA,oBACA,AADA,aACA,sCAA+B,AAA/B,kCAA+B,AAA/B,6BAA+B,CAClC,kBAID,iBACA,gBACA,0BACA,YACA,uBAAyB,CAG3B,0CARF,0BASG,wBAA0B,CAE3B,CAGF,sBAGQ,uBAAyB,CAC5B,yDAIJ,uBAAyB,CACzB,oCAGA,uBAAyB,CACzB,oBAGA,qBACA,AADA,oBACA,AADA,aACA,8BAAuB,AAAvB,0BAAuB,AAAvB,qBAAuB,CAEvB,0CAJD,oBAKQ,2BAAoB,AAApB,uBAAoB,AAApB,kBAAoB,CAE3B,CAED,sBACC,sBAAe,AAAf,kBAAe,AAAf,aAAe,CAEf,0CAHD,sBAIQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAMrB,CAHA,2CAPD,sBAQQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAErB,CAED,qBACC,sBACA,AADA,kBACA,AADA,cACA,cAAgB,CAEhB,0CAJD,qBAKQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAerB,CAZA,2CARD,qBASQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAWrB,CApBD,wBAaE,kBAAoB,CAbtB,+BAiBE,WACA,mBAAqB,CACrB,+CAID,YAAc,CACd,wIAQE,2BAA6B,CAC7B,uCAOD,6CAAS,kBACC,QACL,WACE,WACA,gBACM,gBACF,gBACC,CAAA,0CAEqB,uCAZH,gBAalB,kBACA,MACN,CAAA,CAAG;;ADtPX,oDAAoD","file":"extension-projectino.css"}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* RedmineX
|
||||
* Copyright 2020 RedmineX
|
||||
* For license, see https://www.redmine-x.com
|
||||
* Created by Michael Staněk
|
||||
* Created without vendor prefixes, "AutoPrefixed" by PrePros v5 (https://prepros.io)
|
||||
*/table.list.issues .checkbox{display:none}@media only screen and (min-width: 899px){table.list.issues .checkbox{display:table-cell}}.theme-Redminex .modal input[type="submit"],.theme-Redminex #gantt-save-btn,.theme-Redminex #content>.contextual>.icon-add,.theme-Redminex #content>.contextual .drdn-trigger>.icon-add,.theme-Redminex .projectino-controls input[type="submit"]:first-of-type,.theme-Redminex .controller-timelog #content>.contextual>.icon:not(.icon-edit):not(.icon-add).icon-time-add,.theme-Redminex #actionbar #new-entity,.theme-Redminex #main-menu #new-object,.theme-Redminex #main-menu2 #new-object{background-color:#e20000 !important;border-color:#e20000 !important}.theme-Redminex .modal input[type="submit"]:hover,.theme-Redminex #gantt-save-btn:hover,.theme-Redminex #content>.contextual>.icon-add:hover,.theme-Redminex #content>.contextual .drdn-trigger>.icon-add:hover,.theme-Redminex .projectino-controls input[type="submit"]:first-of-type:hover,.theme-Redminex .controller-timelog #content>.contextual>.icon:not(.icon-edit):not(.icon-add).icon-time-add:hover,.theme-Redminex #actionbar #new-entity:hover,.theme-Redminex #main-menu #new-object:hover,.theme-Redminex #main-menu2 #new-object:hover{background-color:#bc0000 !important;border-color:#bc0000 !important}.theme-Redminex #actionbar .menu-children,.theme-Redminex .gantt_btn_set.gantt_save_btn_set,.theme-Redminex .dhtmlx_popup_controls div[result="save"]{background-color:#e20000 !important}body.theme-Redminex.controller-issues.action-show div.issue.details .btn-primary.validate{background-color:#e20000 !important}body.theme-Redminex.controller-issues.action-show div.issue.details .btn-primary.validate:hover{background-color:#bc0000 !important;border-color:#bc0000 !important}@media only screen and (max-width: 899px){.controller-my.action-page #content>.contextual{display:none}}@media only screen and (max-width: 899px){.controller-my.action-page .contextual .icon-sort-handle,.controller-my.action-page .contextual .icon-settings,.controller-my.action-page .contextual .icon-close{display:none}}.controller-my.action-page #block-starting_with_redmine_x iframe{width:100% !important}.starting-block-box{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}@media only screen and (min-width: 768px){.starting-block-box{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}}.starting-block-video{-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%}@media only screen and (min-width: 768px){.starting-block-video{-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%}}@media only screen and (min-width: 1200px){.starting-block-video{-webkit-flex:0 0 33%;-ms-flex:0 0 33%;flex:0 0 33%}}.starting-block-text{-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;padding:0 2rem}@media only screen and (min-width: 768px){.starting-block-text{-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%}}@media only screen and (min-width: 1200px){.starting-block-text{-webkit-flex:0 0 66%;-ms-flex:0 0 66%;flex:0 0 66%}}.starting-block-text ul{margin-bottom:1rem}.starting-block-text .gravatar{float:left;margin-right:0.5rem}#chat-application{max-height:600px;max-width:366px;height:calc(100vh - 36px);width:366px;display:none !important}@media only screen and (min-width: 899px){#chat-application.d-block{display:block !important}}
|
||||
|
||||
/*# sourceMappingURL=extension-redminex.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../themes/redminex_theme/stylesheets/scss/extension-redminex.scss","../themes/redminex_theme/stylesheets/themes/redminex_theme/stylesheets/scss/extension-redminex.scss"],"names":[],"mappings":"AAAA;;;;;;GCMG,4BAKD,YAAc,CAEd,0CALF,4BAMY,kBAAoB,CAE9B,CAGF,keAWE,oCACA,+BAAiC,CAZnC,whBAeG,oCACA,+BAAiC,CACjC,sJASD,mCAAqC,CACrC,0FAID,mCAAqC,CADtC,gGAIE,oCACA,+BAAiC,CACjC,0CAGF,gDAIY,YAAc,CAErB,CAOO,0CAbZ,kKAcgB,YAAc,CAErB,CAhBT,iEAoBQ,qBAAuB,CAC1B,oBAIJ,qBACA,AADA,oBACA,AADA,aACA,8BAAuB,AAAvB,0BAAuB,AAAvB,qBAAuB,CAEvB,0CAJD,oBAKQ,2BAAoB,AAApB,uBAAoB,AAApB,kBAAoB,CAE3B,CAED,sBACC,sBAAe,AAAf,kBAAe,AAAf,aAAe,CAEf,0CAHD,sBAIQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAMrB,CAHA,2CAPD,sBAQQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAErB,CAED,qBACC,sBACA,AADA,kBACA,AADA,cACA,cAAgB,CAEhB,0CAJD,qBAKQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAerB,CAZA,2CARD,qBASQ,qBAAc,AAAd,iBAAc,AAAd,YAAc,CAWrB,CApBD,wBAaE,kBAAoB,CAbtB,+BAiBE,WACA,mBAAqB,CACrB,kBAIE,iBACA,gBACA,0BACA,YACA,uBAAyB,CAG3B,0CARF,0BASG,wBAA0B,CAE3B,CAAA;;ADhIF,kDAAkD","file":"extension-redminex.css"}
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Default Priorities */
|
||||
/* Priority 1 */
|
||||
.select2-results__option[id*="priority-1"],
|
||||
.select2-selection__rendered[title="1"] {
|
||||
background-color: #00BBB2 !important;
|
||||
}
|
||||
|
||||
/* Priority 2 */
|
||||
.select2-results__option[id*="priority-2"],
|
||||
.select2-selection__rendered[title="2"] {
|
||||
background-color: #cccccc !important;
|
||||
}
|
||||
|
||||
/* Priority 3 */
|
||||
.select2-results__option[id*="priority-3"],
|
||||
.select2-selection__rendered[title="3"] {
|
||||
background-color: #F27D3E !important;
|
||||
}
|
||||
|
||||
/* Priority 4 */
|
||||
.select2-results__option[id*="priority-4"],
|
||||
.select2-selection__rendered[title="4"]{
|
||||
background-color: #fc5c65 !important;
|
||||
}
|
||||
|
||||
/* Priority 5 */
|
||||
.select2-results__option[id*="priority-5"],
|
||||
.select2-selection__rendered[title="5"] {
|
||||
background-color: none !important;
|
||||
background-image: linear-gradient(125deg, #fc5c65 27.78%, #eb3b5a 27.78%, #eb3b5a 50%, #fc5c65 50%, #fc5c65 77.78%, #eb3b5a 77.78%, #eb3b5a 100%) !important;
|
||||
background-size: 43.95px 62.76px;
|
||||
}
|
||||
|
||||
/* Custom Priorities */
|
||||
/* Priority 6 */
|
||||
.select2-results__option[id*="priority-6"],
|
||||
.select2-selection__rendered[title="6"] {
|
||||
background-color: #98F68D !important;
|
||||
}
|
||||
|
||||
/* Priority 7 */
|
||||
.select2-results__option[id*="priority-7"],
|
||||
.select2-selection__rendered[title="7"] {
|
||||
background-color: #8B77CB !important;
|
||||
}
|
||||
|
||||
/* Priority 8 */
|
||||
.select2-results__option[id*="priority-8"],
|
||||
.select2-selection__rendered[title="8"] {
|
||||
background-color: #663F00 !important;
|
||||
}
|
||||
|
||||
/* Priority 9 */
|
||||
.select2-results__option[id*="priority-9"],
|
||||
.select2-selection__rendered[title="9"] {
|
||||
background-color: #F77297 !important;
|
||||
}
|
||||
|
||||
/* Priority 10 */
|
||||
.select2-results__option[id*="priority-10"],
|
||||
.select2-selection__rendered[title="10"] {
|
||||
background-color: #002D78 !important;
|
||||
}
|
||||
|
||||
/* Priority 11 */
|
||||
.select2-results__option[id*="priority-11"],
|
||||
.select2-selection__rendered[title="11"] {
|
||||
background-color: #C49638 !important;
|
||||
}
|
||||
|
||||
/* Priority 12 */
|
||||
.select2-results__option[id*="priority-12"],
|
||||
.select2-selection__rendered[title="12"] {
|
||||
background-color: #F37C3D !important;
|
||||
}
|
||||
|
||||
/* Priority 13 */
|
||||
.select2-results__option[id*="priority-13"],
|
||||
.select2-selection__rendered[title="13"] {
|
||||
background-color: #DAA21C !important;
|
||||
}
|
||||
|
||||
|
||||
/* Interface CSS*/
|
||||
.select2-dropdown,
|
||||
.select2.select2-container {
|
||||
width: 75px !important;
|
||||
}
|
||||
|
||||
.select2-results__option,
|
||||
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
|
||||
opacity: 0.75;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
1
plugins/000_redmine_x_ux_upgrade/assets/stylesheets/select2.min.css
vendored
Executable file
1
plugins/000_redmine_x_ux_upgrade/assets/stylesheets/select2.min.css
vendored
Executable file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,18 @@
|
||||
Font Awesome Pro License
|
||||
------------------------
|
||||
|
||||
Font Awesome Pro is commercial software that requires a paid license. Full
|
||||
Font Awesome Pro license: https://fontawesome.com/license.
|
||||
|
||||
# Commercial License
|
||||
The Font Awesome Pro commercial license allows you to pay for FA Pro once, own
|
||||
it, and use it just about everywhere you'd like.
|
||||
|
||||
# Attribution
|
||||
Attribution is not required by the Font Awesome Pro commercial license.
|
||||
|
||||
# Brand Icons
|
||||
All brand icons are trademarks of their respective owners. The use of these
|
||||
trademarks does not indicate endorsement of the trademark holder by Font
|
||||
Awesome, nor vice versa. **Please do not use brand logos for any purpose except
|
||||
to represent the company, product, or service to which they refer.**
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,998 @@
|
||||
/*!
|
||||
* Font Awesome Pro 5.13.0 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license (Commercial License)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(factory((global['fontawesome-pro-conflict-detection'] = {})));
|
||||
}(this, (function (exports) { 'use strict';
|
||||
|
||||
function _typeof(obj) {
|
||||
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
||||
_typeof = function (obj) {
|
||||
return typeof obj;
|
||||
};
|
||||
} else {
|
||||
_typeof = function (obj) {
|
||||
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
||||
};
|
||||
}
|
||||
|
||||
return _typeof(obj);
|
||||
}
|
||||
|
||||
function _defineProperty(obj, key, value) {
|
||||
if (key in obj) {
|
||||
Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
} else {
|
||||
obj[key] = value;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function _objectSpread(target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i] != null ? arguments[i] : {};
|
||||
var ownKeys = Object.keys(source);
|
||||
|
||||
if (typeof Object.getOwnPropertySymbols === 'function') {
|
||||
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
|
||||
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
||||
}));
|
||||
}
|
||||
|
||||
ownKeys.forEach(function (key) {
|
||||
_defineProperty(target, key, source[key]);
|
||||
});
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
var _WINDOW = {};
|
||||
var _DOCUMENT = {};
|
||||
|
||||
try {
|
||||
if (typeof window !== 'undefined') _WINDOW = window;
|
||||
if (typeof document !== 'undefined') _DOCUMENT = document;
|
||||
} catch (e) {}
|
||||
|
||||
var _ref = _WINDOW.navigator || {},
|
||||
_ref$userAgent = _ref.userAgent,
|
||||
userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;
|
||||
|
||||
var WINDOW = _WINDOW;
|
||||
var DOCUMENT = _DOCUMENT;
|
||||
var IS_BROWSER = !!WINDOW.document;
|
||||
var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';
|
||||
var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');
|
||||
|
||||
var functions = [];
|
||||
|
||||
var listener = function listener() {
|
||||
DOCUMENT.removeEventListener('DOMContentLoaded', listener);
|
||||
loaded = 1;
|
||||
functions.map(function (fn) {
|
||||
return fn();
|
||||
});
|
||||
};
|
||||
|
||||
var loaded = false;
|
||||
|
||||
if (IS_DOM) {
|
||||
loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);
|
||||
if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);
|
||||
}
|
||||
|
||||
function domready (fn) {
|
||||
if (!IS_DOM) return;
|
||||
loaded ? setTimeout(fn, 0) : functions.push(fn);
|
||||
}
|
||||
|
||||
function report (_ref) {
|
||||
var nodesTested = _ref.nodesTested,
|
||||
nodesFound = _ref.nodesFound;
|
||||
var timedOutTests = {};
|
||||
|
||||
for (var key in nodesFound) {
|
||||
if (!(nodesTested.conflict[key] || nodesTested.noConflict[key])) {
|
||||
timedOutTests[key] = nodesFound[key];
|
||||
}
|
||||
}
|
||||
|
||||
var conflictsCount = Object.keys(nodesTested.conflict).length;
|
||||
|
||||
if (conflictsCount > 0) {
|
||||
console.info("%cConflict".concat(conflictsCount > 1 ? 's' : '', " found:"), 'color: darkred; font-size: large');
|
||||
var data = {};
|
||||
|
||||
for (var _key in nodesTested.conflict) {
|
||||
var item = nodesTested.conflict[_key];
|
||||
data[_key] = {
|
||||
'tagName': item.tagName,
|
||||
'src/href': item.src || item.href || 'n/a',
|
||||
'innerText excerpt': item.innerText && item.innerText !== '' ? item.innerText.slice(0, 200) + '...' : '(empty)'
|
||||
};
|
||||
}
|
||||
|
||||
console.table(data);
|
||||
}
|
||||
|
||||
var noConflictsCount = Object.keys(nodesTested.noConflict).length;
|
||||
|
||||
if (noConflictsCount > 0) {
|
||||
console.info("%cNo conflict".concat(noConflictsCount > 1 ? 's' : '', " found with ").concat(noConflictsCount == 1 ? 'this' : 'these', ":"), 'color: green; font-size: large');
|
||||
var _data = {};
|
||||
|
||||
for (var _key2 in nodesTested.noConflict) {
|
||||
var _item = nodesTested.noConflict[_key2];
|
||||
_data[_key2] = {
|
||||
'tagName': _item.tagName,
|
||||
'src/href': _item.src || _item.href || 'n/a',
|
||||
'innerText excerpt': _item.innerText && _item.innerText !== '' ? _item.innerText.slice(0, 200) + '...' : '(empty)'
|
||||
};
|
||||
}
|
||||
|
||||
console.table(_data);
|
||||
}
|
||||
|
||||
var timeOutCount = Object.keys(timedOutTests).length;
|
||||
|
||||
if (timeOutCount > 0) {
|
||||
console.info("%cLeftovers--we timed out before collecting test results for ".concat(timeOutCount == 1 ? 'this' : 'these', ":"), 'color: blue; font-size: large');
|
||||
var _data2 = {};
|
||||
|
||||
for (var _key3 in timedOutTests) {
|
||||
var _item2 = timedOutTests[_key3];
|
||||
_data2[_key3] = {
|
||||
'tagName': _item2.tagName,
|
||||
'src/href': _item2.src || _item2.href || 'n/a',
|
||||
'innerText excerpt': _item2.innerText && _item2.innerText !== '' ? _item2.innerText.slice(0, 200) + '...' : '(empty)'
|
||||
};
|
||||
}
|
||||
|
||||
console.table(_data2);
|
||||
}
|
||||
}
|
||||
|
||||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
||||
|
||||
function createCommonjsModule(fn, module) {
|
||||
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
||||
}
|
||||
|
||||
var md5 = createCommonjsModule(function (module) {
|
||||
|
||||
(function ($) {
|
||||
/**
|
||||
* Add integers, wrapping at 2^32.
|
||||
* This uses 16-bit operations internally to work around bugs in interpreters.
|
||||
*
|
||||
* @param {number} x First integer
|
||||
* @param {number} y Second integer
|
||||
* @returns {number} Sum
|
||||
*/
|
||||
|
||||
function safeAdd(x, y) {
|
||||
var lsw = (x & 0xffff) + (y & 0xffff);
|
||||
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
return msw << 16 | lsw & 0xffff;
|
||||
}
|
||||
/**
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*
|
||||
* @param {number} num 32-bit number
|
||||
* @param {number} cnt Rotation count
|
||||
* @returns {number} Rotated number
|
||||
*/
|
||||
|
||||
|
||||
function bitRotateLeft(num, cnt) {
|
||||
return num << cnt | num >>> 32 - cnt;
|
||||
}
|
||||
/**
|
||||
* Basic operation the algorithm uses.
|
||||
*
|
||||
* @param {number} q q
|
||||
* @param {number} a a
|
||||
* @param {number} b b
|
||||
* @param {number} x x
|
||||
* @param {number} s s
|
||||
* @param {number} t t
|
||||
* @returns {number} Result
|
||||
*/
|
||||
|
||||
|
||||
function md5cmn(q, a, b, x, s, t) {
|
||||
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
|
||||
}
|
||||
/**
|
||||
* Basic operation the algorithm uses.
|
||||
*
|
||||
* @param {number} a a
|
||||
* @param {number} b b
|
||||
* @param {number} c c
|
||||
* @param {number} d d
|
||||
* @param {number} x x
|
||||
* @param {number} s s
|
||||
* @param {number} t t
|
||||
* @returns {number} Result
|
||||
*/
|
||||
|
||||
|
||||
function md5ff(a, b, c, d, x, s, t) {
|
||||
return md5cmn(b & c | ~b & d, a, b, x, s, t);
|
||||
}
|
||||
/**
|
||||
* Basic operation the algorithm uses.
|
||||
*
|
||||
* @param {number} a a
|
||||
* @param {number} b b
|
||||
* @param {number} c c
|
||||
* @param {number} d d
|
||||
* @param {number} x x
|
||||
* @param {number} s s
|
||||
* @param {number} t t
|
||||
* @returns {number} Result
|
||||
*/
|
||||
|
||||
|
||||
function md5gg(a, b, c, d, x, s, t) {
|
||||
return md5cmn(b & d | c & ~d, a, b, x, s, t);
|
||||
}
|
||||
/**
|
||||
* Basic operation the algorithm uses.
|
||||
*
|
||||
* @param {number} a a
|
||||
* @param {number} b b
|
||||
* @param {number} c c
|
||||
* @param {number} d d
|
||||
* @param {number} x x
|
||||
* @param {number} s s
|
||||
* @param {number} t t
|
||||
* @returns {number} Result
|
||||
*/
|
||||
|
||||
|
||||
function md5hh(a, b, c, d, x, s, t) {
|
||||
return md5cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
/**
|
||||
* Basic operation the algorithm uses.
|
||||
*
|
||||
* @param {number} a a
|
||||
* @param {number} b b
|
||||
* @param {number} c c
|
||||
* @param {number} d d
|
||||
* @param {number} x x
|
||||
* @param {number} s s
|
||||
* @param {number} t t
|
||||
* @returns {number} Result
|
||||
*/
|
||||
|
||||
|
||||
function md5ii(a, b, c, d, x, s, t) {
|
||||
return md5cmn(c ^ (b | ~d), a, b, x, s, t);
|
||||
}
|
||||
/**
|
||||
* Calculate the MD5 of an array of little-endian words, and a bit length.
|
||||
*
|
||||
* @param {Array} x Array of little-endian words
|
||||
* @param {number} len Bit length
|
||||
* @returns {Array<number>} MD5 Array
|
||||
*/
|
||||
|
||||
|
||||
function binlMD5(x, len) {
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << len % 32;
|
||||
x[(len + 64 >>> 9 << 4) + 14] = len;
|
||||
var i;
|
||||
var olda;
|
||||
var oldb;
|
||||
var oldc;
|
||||
var oldd;
|
||||
var a = 1732584193;
|
||||
var b = -271733879;
|
||||
var c = -1732584194;
|
||||
var d = 271733878;
|
||||
|
||||
for (i = 0; i < x.length; i += 16) {
|
||||
olda = a;
|
||||
oldb = b;
|
||||
oldc = c;
|
||||
oldd = d;
|
||||
a = md5ff(a, b, c, d, x[i], 7, -680876936);
|
||||
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
|
||||
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
|
||||
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
|
||||
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
|
||||
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
|
||||
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
|
||||
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
|
||||
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
|
||||
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
|
||||
c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
|
||||
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
|
||||
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
|
||||
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
|
||||
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
|
||||
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
|
||||
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
|
||||
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
|
||||
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
|
||||
b = md5gg(b, c, d, a, x[i], 20, -373897302);
|
||||
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
|
||||
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
|
||||
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
|
||||
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
|
||||
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
|
||||
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
|
||||
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
|
||||
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
|
||||
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
|
||||
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
|
||||
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
|
||||
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
|
||||
a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
|
||||
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
|
||||
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
|
||||
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
|
||||
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
|
||||
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
|
||||
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
|
||||
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
|
||||
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
|
||||
d = md5hh(d, a, b, c, x[i], 11, -358537222);
|
||||
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
|
||||
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
|
||||
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
|
||||
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
|
||||
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
|
||||
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
|
||||
a = md5ii(a, b, c, d, x[i], 6, -198630844);
|
||||
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
|
||||
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
|
||||
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
|
||||
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
|
||||
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
|
||||
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
|
||||
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
|
||||
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
|
||||
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
|
||||
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
|
||||
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
|
||||
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
|
||||
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
|
||||
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
|
||||
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
|
||||
a = safeAdd(a, olda);
|
||||
b = safeAdd(b, oldb);
|
||||
c = safeAdd(c, oldc);
|
||||
d = safeAdd(d, oldd);
|
||||
}
|
||||
|
||||
return [a, b, c, d];
|
||||
}
|
||||
/**
|
||||
* Convert an array of little-endian words to a string
|
||||
*
|
||||
* @param {Array<number>} input MD5 Array
|
||||
* @returns {string} MD5 string
|
||||
*/
|
||||
|
||||
|
||||
function binl2rstr(input) {
|
||||
var i;
|
||||
var output = '';
|
||||
var length32 = input.length * 32;
|
||||
|
||||
for (i = 0; i < length32; i += 8) {
|
||||
output += String.fromCharCode(input[i >> 5] >>> i % 32 & 0xff);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
/**
|
||||
* Convert a raw string to an array of little-endian words
|
||||
* Characters >255 have their high-byte silently ignored.
|
||||
*
|
||||
* @param {string} input Raw input string
|
||||
* @returns {Array<number>} Array of little-endian words
|
||||
*/
|
||||
|
||||
|
||||
function rstr2binl(input) {
|
||||
var i;
|
||||
var output = [];
|
||||
output[(input.length >> 2) - 1] = undefined;
|
||||
|
||||
for (i = 0; i < output.length; i += 1) {
|
||||
output[i] = 0;
|
||||
}
|
||||
|
||||
var length8 = input.length * 8;
|
||||
|
||||
for (i = 0; i < length8; i += 8) {
|
||||
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
/**
|
||||
* Calculate the MD5 of a raw string
|
||||
*
|
||||
* @param {string} s Input string
|
||||
* @returns {string} Raw MD5 string
|
||||
*/
|
||||
|
||||
|
||||
function rstrMD5(s) {
|
||||
return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));
|
||||
}
|
||||
/**
|
||||
* Calculates the HMAC-MD5 of a key and some data (raw strings)
|
||||
*
|
||||
* @param {string} key HMAC key
|
||||
* @param {string} data Raw input string
|
||||
* @returns {string} Raw MD5 string
|
||||
*/
|
||||
|
||||
|
||||
function rstrHMACMD5(key, data) {
|
||||
var i;
|
||||
var bkey = rstr2binl(key);
|
||||
var ipad = [];
|
||||
var opad = [];
|
||||
var hash;
|
||||
ipad[15] = opad[15] = undefined;
|
||||
|
||||
if (bkey.length > 16) {
|
||||
bkey = binlMD5(bkey, key.length * 8);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
ipad[i] = bkey[i] ^ 0x36363636;
|
||||
opad[i] = bkey[i] ^ 0x5c5c5c5c;
|
||||
}
|
||||
|
||||
hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
|
||||
return binl2rstr(binlMD5(opad.concat(hash), 512 + 128));
|
||||
}
|
||||
/**
|
||||
* Convert a raw string to a hex string
|
||||
*
|
||||
* @param {string} input Raw input string
|
||||
* @returns {string} Hex encoded string
|
||||
*/
|
||||
|
||||
|
||||
function rstr2hex(input) {
|
||||
var hexTab = '0123456789abcdef';
|
||||
var output = '';
|
||||
var x;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < input.length; i += 1) {
|
||||
x = input.charCodeAt(i);
|
||||
output += hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
/**
|
||||
* Encode a string as UTF-8
|
||||
*
|
||||
* @param {string} input Input string
|
||||
* @returns {string} UTF8 string
|
||||
*/
|
||||
|
||||
|
||||
function str2rstrUTF8(input) {
|
||||
return unescape(encodeURIComponent(input));
|
||||
}
|
||||
/**
|
||||
* Encodes input string as raw MD5 string
|
||||
*
|
||||
* @param {string} s Input string
|
||||
* @returns {string} Raw MD5 string
|
||||
*/
|
||||
|
||||
|
||||
function rawMD5(s) {
|
||||
return rstrMD5(str2rstrUTF8(s));
|
||||
}
|
||||
/**
|
||||
* Encodes input string as Hex encoded string
|
||||
*
|
||||
* @param {string} s Input string
|
||||
* @returns {string} Hex encoded string
|
||||
*/
|
||||
|
||||
|
||||
function hexMD5(s) {
|
||||
return rstr2hex(rawMD5(s));
|
||||
}
|
||||
/**
|
||||
* Calculates the raw HMAC-MD5 for the given key and data
|
||||
*
|
||||
* @param {string} k HMAC key
|
||||
* @param {string} d Input string
|
||||
* @returns {string} Raw MD5 string
|
||||
*/
|
||||
|
||||
|
||||
function rawHMACMD5(k, d) {
|
||||
return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));
|
||||
}
|
||||
/**
|
||||
* Calculates the Hex encoded HMAC-MD5 for the given key and data
|
||||
*
|
||||
* @param {string} k HMAC key
|
||||
* @param {string} d Input string
|
||||
* @returns {string} Raw MD5 string
|
||||
*/
|
||||
|
||||
|
||||
function hexHMACMD5(k, d) {
|
||||
return rstr2hex(rawHMACMD5(k, d));
|
||||
}
|
||||
/**
|
||||
* Calculates MD5 value for a given string.
|
||||
* If a key is provided, calculates the HMAC-MD5 value.
|
||||
* Returns a Hex encoded string unless the raw argument is given.
|
||||
*
|
||||
* @param {string} string Input string
|
||||
* @param {string} [key] HMAC key
|
||||
* @param {boolean} raw Raw oytput switch
|
||||
* @returns {string} MD5 output
|
||||
*/
|
||||
|
||||
|
||||
function md5(string, key, raw) {
|
||||
if (!key) {
|
||||
if (!raw) {
|
||||
return hexMD5(string);
|
||||
}
|
||||
|
||||
return rawMD5(string);
|
||||
}
|
||||
|
||||
if (!raw) {
|
||||
return hexHMACMD5(key, string);
|
||||
}
|
||||
|
||||
return rawHMACMD5(key, string);
|
||||
}
|
||||
|
||||
if (module.exports) {
|
||||
module.exports = md5;
|
||||
} else {
|
||||
$.md5 = md5;
|
||||
}
|
||||
})(commonjsGlobal);
|
||||
});
|
||||
|
||||
function md5ForNode(node) {
|
||||
if (null === node || 'object' !== _typeof(node)) return undefined;
|
||||
|
||||
if (node.src) {
|
||||
return md5(node.src);
|
||||
} else if (node.href) {
|
||||
return md5(node.href);
|
||||
} else if (node.innerText && '' !== node.innerText) {
|
||||
// eslint-disable-line yoda
|
||||
return md5(node.innerText);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
var diagScriptId = 'fa-kits-diag';
|
||||
var nodeUnderTestId = 'fa-kits-node-under-test';
|
||||
var md5Attr = 'data-md5';
|
||||
var detectionIgnoreAttr = 'data-fa-detection-ignore';
|
||||
var timeoutAttr = 'data-fa-detection-timeout';
|
||||
var resultsCollectionMaxWaitAttr = 'data-fa-detection-results-collection-max-wait';
|
||||
|
||||
var silenceErrors = function silenceErrors(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
function pollUntil(_ref) {
|
||||
var _ref$fn = _ref.fn,
|
||||
fn = _ref$fn === void 0 ? function () {
|
||||
return true;
|
||||
} : _ref$fn,
|
||||
_ref$initialDuration = _ref.initialDuration,
|
||||
initialDuration = _ref$initialDuration === void 0 ? 1 : _ref$initialDuration,
|
||||
_ref$maxDuration = _ref.maxDuration,
|
||||
maxDuration = _ref$maxDuration === void 0 ? WINDOW.FontAwesomeDetection.timeout : _ref$maxDuration,
|
||||
_ref$showProgress = _ref.showProgress,
|
||||
showProgress = _ref$showProgress === void 0 ? false : _ref$showProgress,
|
||||
progressIndicator = _ref.progressIndicator;
|
||||
return new Promise(function (resolve, reject) {
|
||||
// eslint-disable-line compat/compat
|
||||
function poll(duration, cumulativeDuration) {
|
||||
setTimeout(function () {
|
||||
var result = fn();
|
||||
|
||||
if (showProgress) {
|
||||
console.info(progressIndicator);
|
||||
}
|
||||
|
||||
if (!!result) {
|
||||
// eslint-disable-line no-extra-boolean-cast
|
||||
resolve(result);
|
||||
} else {
|
||||
var nextDuration = 250;
|
||||
var nextCumulativeDuration = nextDuration + cumulativeDuration;
|
||||
|
||||
if (nextCumulativeDuration <= maxDuration) {
|
||||
poll(nextDuration, nextCumulativeDuration);
|
||||
} else {
|
||||
reject('timeout'); // eslint-disable-line prefer-promise-reject-errors
|
||||
}
|
||||
}
|
||||
}, duration);
|
||||
}
|
||||
|
||||
poll(initialDuration, 0);
|
||||
});
|
||||
}
|
||||
|
||||
function detectWebfontConflicts() {
|
||||
var linkTags = Array.from(DOCUMENT.getElementsByTagName('link')).filter(function (t) {
|
||||
return !t.hasAttribute(detectionIgnoreAttr);
|
||||
});
|
||||
var styleTags = Array.from(DOCUMENT.getElementsByTagName('style')).filter(function (t) {
|
||||
if (t.hasAttribute(detectionIgnoreAttr)) {
|
||||
return false;
|
||||
} // If the browser has loaded the FA5 CSS, let's not test that <style> element.
|
||||
// Its enough that we'll be testing for traces of the corresponding JS being loaded, and testing
|
||||
// this <style> would only produce a false negative anyway.
|
||||
|
||||
|
||||
if (WINDOW.FontAwesomeConfig && t.innerText.match(new RegExp("svg:not\\(:root\\)\\.".concat(WINDOW.FontAwesomeConfig.replacementClass)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
function runDiag(scriptOrLinkTag, md5) {
|
||||
var diagFrame = DOCUMENT.createElement('iframe'); // Using "visibility: hidden; position: absolute" instead of "display: none;" because
|
||||
// Firefox will not return the expected results for getComputedStyle if our iframe has display: none.
|
||||
|
||||
diagFrame.setAttribute('style', 'visibility: hidden; position: absolute; height: 0; width: 0;');
|
||||
var testIconId = 'fa-test-icon-' + md5;
|
||||
var iTag = DOCUMENT.createElement('i');
|
||||
iTag.setAttribute('class', 'fa fa-coffee');
|
||||
iTag.setAttribute('id', testIconId);
|
||||
var diagScript = DOCUMENT.createElement('script');
|
||||
diagScript.setAttribute('id', diagScriptId); // WARNING: this function will be toString()'d and assigned to innerText of the diag script
|
||||
// element that we'll be putting into a diagnostic iframe.
|
||||
// That means that this code won't compile until after the outer script has run and injected
|
||||
// this code into the iframe. There are some compile time errors that might occur there.
|
||||
// For example, using single line (double-slash) comments like this one inside that function
|
||||
// will probably cause it to choke. Chrome will show an error like this:
|
||||
// Uncaught SyntaxError: Unexpected end of input
|
||||
|
||||
var diagScriptFun = function diagScriptFun(nodeUnderTestId, testIconId, md5, parentOrigin) {
|
||||
parent.FontAwesomeDetection.__pollUntil({
|
||||
fn: function fn() {
|
||||
var iEl = document.getElementById(testIconId);
|
||||
var computedStyle = window.getComputedStyle(iEl);
|
||||
var fontFamily = computedStyle.getPropertyValue('font-family');
|
||||
|
||||
if (!!fontFamily.match(/FontAwesome/) || !!fontFamily.match(/Font Awesome 5/)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}).then(function () {
|
||||
var node = document.getElementById(nodeUnderTestId);
|
||||
parent.postMessage({
|
||||
type: 'fontawesome-conflict',
|
||||
technology: 'webfont',
|
||||
href: node.href,
|
||||
innerText: node.innerText,
|
||||
tagName: node.tagName,
|
||||
md5: md5
|
||||
}, parentOrigin);
|
||||
}).catch(function (e) {
|
||||
var node = document.getElementById(nodeUnderTestId);
|
||||
|
||||
if (e === 'timeout') {
|
||||
parent.postMessage({
|
||||
type: 'no-conflict',
|
||||
technology: 'webfont',
|
||||
href: node.src,
|
||||
innerText: node.innerText,
|
||||
tagName: node.tagName,
|
||||
md5: md5
|
||||
}, parentOrigin);
|
||||
} else {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var parentOrigin = WINDOW.location.origin === 'file://' ? '*' : WINDOW.location.origin;
|
||||
diagScript.innerText = "(".concat(diagScriptFun.toString(), ")('").concat(nodeUnderTestId, "', '").concat(testIconId || 'foo', "', '").concat(md5, "', '").concat(parentOrigin, "');");
|
||||
|
||||
diagFrame.onload = function () {
|
||||
diagFrame.contentWindow.addEventListener('error', silenceErrors, true);
|
||||
diagFrame.contentDocument.head.appendChild(diagScript);
|
||||
diagFrame.contentDocument.head.appendChild(scriptOrLinkTag);
|
||||
diagFrame.contentDocument.body.appendChild(iTag);
|
||||
};
|
||||
|
||||
domready(function () {
|
||||
return DOCUMENT.body.appendChild(diagFrame);
|
||||
});
|
||||
}
|
||||
|
||||
var cssByMD5 = {};
|
||||
|
||||
for (var i = 0; i < linkTags.length; i++) {
|
||||
var linkUnderTest = DOCUMENT.createElement('link');
|
||||
linkUnderTest.setAttribute('id', nodeUnderTestId);
|
||||
linkUnderTest.setAttribute('href', linkTags[i].href);
|
||||
linkUnderTest.setAttribute('rel', linkTags[i].rel);
|
||||
var md5ForLink = md5ForNode(linkTags[i]);
|
||||
linkUnderTest.setAttribute(md5Attr, md5ForLink);
|
||||
cssByMD5[md5ForLink] = linkTags[i];
|
||||
runDiag(linkUnderTest, md5ForLink);
|
||||
}
|
||||
|
||||
for (var _i = 0; _i < styleTags.length; _i++) {
|
||||
var styleUnderTest = DOCUMENT.createElement('style');
|
||||
styleUnderTest.setAttribute('id', nodeUnderTestId);
|
||||
var md5ForStyle = md5ForNode(styleTags[_i]);
|
||||
styleUnderTest.setAttribute(md5Attr, md5ForStyle);
|
||||
styleUnderTest.innerText = styleTags[_i].innerText;
|
||||
cssByMD5[md5ForStyle] = styleTags[_i];
|
||||
runDiag(styleUnderTest, md5ForStyle);
|
||||
}
|
||||
|
||||
return cssByMD5;
|
||||
}
|
||||
|
||||
function detectSvgConflicts(currentScript) {
|
||||
var scripts = Array.from(DOCUMENT.scripts).filter(function (t) {
|
||||
return !t.hasAttribute(detectionIgnoreAttr) && t !== currentScript;
|
||||
});
|
||||
var scriptsByMD5 = {};
|
||||
|
||||
var _loop = function _loop(scriptIdx) {
|
||||
var diagFrame = DOCUMENT.createElement('iframe');
|
||||
diagFrame.setAttribute('style', 'display:none;');
|
||||
var scriptUnderTest = DOCUMENT.createElement('script');
|
||||
scriptUnderTest.setAttribute('id', nodeUnderTestId);
|
||||
var md5ForScript = md5ForNode(scripts[scriptIdx]);
|
||||
scriptUnderTest.setAttribute(md5Attr, md5ForScript);
|
||||
scriptsByMD5[md5ForScript] = scripts[scriptIdx];
|
||||
|
||||
if (scripts[scriptIdx].src !== '') {
|
||||
scriptUnderTest.src = scripts[scriptIdx].src;
|
||||
}
|
||||
|
||||
if (scripts[scriptIdx].innerText !== '') {
|
||||
scriptUnderTest.innerText = scripts[scriptIdx].innerText;
|
||||
}
|
||||
|
||||
scriptUnderTest.async = true;
|
||||
var diagScript = DOCUMENT.createElement('script');
|
||||
diagScript.setAttribute('id', diagScriptId);
|
||||
var parentOrigin = WINDOW.location.origin === 'file://' ? '*' : WINDOW.location.origin;
|
||||
|
||||
var diagScriptFun = function diagScriptFun(nodeUnderTestId, md5, parentOrigin) {
|
||||
parent.FontAwesomeDetection.__pollUntil({
|
||||
fn: function fn() {
|
||||
return !!window.FontAwesomeConfig;
|
||||
}
|
||||
}).then(function () {
|
||||
var scriptNode = document.getElementById(nodeUnderTestId);
|
||||
parent.postMessage({
|
||||
type: 'fontawesome-conflict',
|
||||
technology: 'js',
|
||||
src: scriptNode.src,
|
||||
innerText: scriptNode.innerText,
|
||||
tagName: scriptNode.tagName,
|
||||
md5: md5
|
||||
}, parentOrigin);
|
||||
}).catch(function (e) {
|
||||
var scriptNode = document.getElementById(nodeUnderTestId);
|
||||
|
||||
if (e === 'timeout') {
|
||||
parent.postMessage({
|
||||
type: 'no-conflict',
|
||||
src: scriptNode.src,
|
||||
innerText: scriptNode.innerText,
|
||||
tagName: scriptNode.tagName,
|
||||
md5: md5
|
||||
}, parentOrigin);
|
||||
} else {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
diagScript.innerText = "(".concat(diagScriptFun.toString(), ")('").concat(nodeUnderTestId, "', '").concat(md5ForScript, "', '").concat(parentOrigin, "');");
|
||||
|
||||
diagFrame.onload = function () {
|
||||
diagFrame.contentWindow.addEventListener('error', silenceErrors, true);
|
||||
diagFrame.contentDocument.head.appendChild(diagScript);
|
||||
diagFrame.contentDocument.head.appendChild(scriptUnderTest);
|
||||
};
|
||||
|
||||
domready(function () {
|
||||
return DOCUMENT.body.appendChild(diagFrame);
|
||||
});
|
||||
};
|
||||
|
||||
for (var scriptIdx = 0; scriptIdx < scripts.length; scriptIdx++) {
|
||||
_loop(scriptIdx);
|
||||
}
|
||||
|
||||
return scriptsByMD5;
|
||||
}
|
||||
|
||||
function setDoneResults(_ref2) {
|
||||
var nodesTested = _ref2.nodesTested,
|
||||
nodesFound = _ref2.nodesFound;
|
||||
WINDOW.FontAwesomeDetection = WINDOW.FontAwesomeDetection || {};
|
||||
WINDOW.FontAwesomeDetection.nodesTested = nodesTested;
|
||||
WINDOW.FontAwesomeDetection.nodesFound = nodesFound;
|
||||
WINDOW.FontAwesomeDetection.detectionDone = true;
|
||||
}
|
||||
|
||||
function conflictDetection() {
|
||||
var report$$1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
|
||||
var nodesTested = {
|
||||
conflict: {},
|
||||
noConflict: {}
|
||||
};
|
||||
|
||||
WINDOW.onmessage = function (e) {
|
||||
if (WINDOW.location.origin === 'file://' || e.origin === WINDOW.location.origin) {
|
||||
if (e && e.data) {
|
||||
if (e.data.type === 'fontawesome-conflict') {
|
||||
nodesTested.conflict[e.data.md5] = e.data;
|
||||
} else if (e.data.type === 'no-conflict') {
|
||||
nodesTested.noConflict[e.data.md5] = e.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var scriptsToTest = detectSvgConflicts(DOCUMENT.currentScript);
|
||||
var cssToTest = detectWebfontConflicts();
|
||||
|
||||
var nodesFound = _objectSpread({}, scriptsToTest, cssToTest);
|
||||
|
||||
var testCount = Object.keys(scriptsToTest).length + Object.keys(cssToTest).length; // The resultsCollectionMaxWait allows for the time between when the tests running under
|
||||
// child iframes call postMessage with their results, and when the parent window
|
||||
// receives and handles those events with window.onmessage.
|
||||
// Making it configurable allows us to test the scenario where this timeout is exceeded.
|
||||
// Naming it something very different from "timeout" is to help avoid the potential ambiguity between
|
||||
// these two timeout-related settings.
|
||||
|
||||
var masterTimeout = WINDOW.FontAwesomeDetection.timeout + WINDOW.FontAwesomeDetection.resultsCollectionMaxWait;
|
||||
console.group('Font Awesome Detector');
|
||||
|
||||
if (testCount === 0) {
|
||||
console.info('%cAll Good!', 'color: green; font-size: large');
|
||||
console.info('We didn\'t find anything that needs testing for conflicts. Ergo, no conflicts.');
|
||||
} else {
|
||||
console.info("Testing ".concat(testCount, " possible conflicts."));
|
||||
console.info("We'll wait about ".concat(Math.round(WINDOW.FontAwesomeDetection.timeout / 10) / 100, " seconds while testing these and\n") + "then up to another ".concat(Math.round(WINDOW.FontAwesomeDetection.resultsCollectionMaxWait / 10) / 100, " to allow the browser time\n") + "to accumulate the results. But we'll probably be outta here way before then.\n\n");
|
||||
console.info("You can adjust those durations by assigning values to these attributes on the <script> element that loads this detection:");
|
||||
console.info("\t%c".concat(timeoutAttr, "%c: milliseconds to wait for each test before deciding whether it's a conflict."), 'font-weight: bold;', 'font-size: normal;');
|
||||
console.info("\t%c".concat(resultsCollectionMaxWaitAttr, "%c: milliseconds to wait for the browser to accumulate test results before giving up."), 'font-weight: bold;', 'font-size: normal;');
|
||||
pollUntil({
|
||||
// Give this overall timer a little extra cushion
|
||||
maxDuration: masterTimeout,
|
||||
showProgress: true,
|
||||
progressIndicator: 'waiting...',
|
||||
fn: function fn() {
|
||||
return Object.keys(nodesTested.conflict).length + Object.keys(nodesTested.noConflict).length >= testCount;
|
||||
}
|
||||
}).then(function () {
|
||||
console.info('DONE!');
|
||||
setDoneResults({
|
||||
nodesTested: nodesTested,
|
||||
nodesFound: nodesFound
|
||||
});
|
||||
report$$1({
|
||||
nodesTested: nodesTested,
|
||||
nodesFound: nodesFound
|
||||
});
|
||||
console.groupEnd();
|
||||
}).catch(function (e) {
|
||||
if (e === 'timeout') {
|
||||
console.info('TIME OUT! We waited until we got tired. Here\'s what we found:');
|
||||
setDoneResults({
|
||||
nodesTested: nodesTested,
|
||||
nodesFound: nodesFound
|
||||
});
|
||||
report$$1({
|
||||
nodesTested: nodesTested,
|
||||
nodesFound: nodesFound
|
||||
});
|
||||
} else {
|
||||
console.info('Whoops! We hit an error:', e);
|
||||
console.info('Here\'s what we\'d found up until that error:');
|
||||
setDoneResults({
|
||||
nodesTested: nodesTested,
|
||||
nodesFound: nodesFound
|
||||
});
|
||||
report$$1({
|
||||
nodesTested: nodesTested,
|
||||
nodesFound: nodesFound
|
||||
});
|
||||
}
|
||||
|
||||
console.groupEnd();
|
||||
});
|
||||
}
|
||||
} // Allow clients to access, and in some cases, override some properties
|
||||
|
||||
var initialConfig = WINDOW.FontAwesomeDetection || {}; // These can be overridden
|
||||
|
||||
var _default = {
|
||||
report: report,
|
||||
timeout: +(DOCUMENT.currentScript.getAttribute(timeoutAttr) || "2000"),
|
||||
resultsCollectionMaxWait: +(DOCUMENT.currentScript.getAttribute(resultsCollectionMaxWaitAttr) || "5000")
|
||||
};
|
||||
|
||||
var _config = _objectSpread({}, _default, initialConfig, {
|
||||
// These cannot be overridden
|
||||
__pollUntil: pollUntil,
|
||||
md5ForNode: md5ForNode,
|
||||
detectionDone: false,
|
||||
nodesTested: null,
|
||||
nodesFound: null
|
||||
});
|
||||
|
||||
WINDOW.FontAwesomeDetection = _config;
|
||||
|
||||
var PRODUCTION = function () {
|
||||
try {
|
||||
return process.env.NODE_ENV === 'production';
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}();
|
||||
|
||||
function bunker(fn) {
|
||||
try {
|
||||
fn();
|
||||
} catch (e) {
|
||||
if (!PRODUCTION) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bunker(function () {
|
||||
if (IS_BROWSER && IS_DOM) {
|
||||
conflictDetection(window.FontAwesomeDetection.report);
|
||||
}
|
||||
});
|
||||
|
||||
exports.conflictDetection = conflictDetection;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
})));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user