From a925ffbf2a39d6f543c99d214f55536cd8100387 Mon Sep 17 00:00:00 2001 From: murin Date: Tue, 22 Oct 2024 15:25:32 +0300 Subject: Increase maximum size for custom field name --- app/models/custom_field.rb | 2 +- .../20241016120800_change_custom_fields_name_limit.rb | 9 +++++++++ test/unit/custom_field_test.rb | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20241016120800_change_custom_fields_name_limit.rb diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index d14b67bdb..ba7d22371 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -35,7 +35,7 @@ class CustomField < ApplicationRecord validates_presence_of :name, :field_format validates_uniqueness_of :name, :scope => :type, :case_sensitive => true - validates_length_of :name, :maximum => 30 + validates_length_of :name, maximum: 255 validates_length_of :regexp, maximum: 255 validates_inclusion_of :field_format, :in => proc {Redmine::FieldFormat.available_formats} diff --git a/db/migrate/20241016120800_change_custom_fields_name_limit.rb b/db/migrate/20241016120800_change_custom_fields_name_limit.rb new file mode 100644 index 000000000..07760e1ee --- /dev/null +++ b/db/migrate/20241016120800_change_custom_fields_name_limit.rb @@ -0,0 +1,9 @@ +class ChangeCustomFieldsNameLimit < ActiveRecord::Migration[7.2] + def up + change_column :custom_fields, :name, :string, limit: 255, default: '' + end + + def down + change_column :custom_fields, :name, :string, limit: 30, default: '' + end +end diff --git a/test/unit/custom_field_test.rb b/test/unit/custom_field_test.rb index 608176559..be3c74532 100644 --- a/test/unit/custom_field_test.rb +++ b/test/unit/custom_field_test.rb @@ -48,6 +48,11 @@ class CustomFieldTest < ActiveSupport::TestCase assert field.save end + def test_name_should_be_validated + field = CustomField.new(name: 'Very long custom field name' * 10, field_format: 'int') + assert field.invalid? + end + def test_default_value_should_be_validated field = CustomField.new(:name => 'Test', :field_format => 'int') field.default_value = 'abc' -- 2.25.1 From 6f0224a786fdd402c4d8e250e795d0304c864293 Mon Sep 17 00:00:00 2001 From: murin Date: Thu, 7 Nov 2024 14:03:56 +0300 Subject: Limit max width for selects in query form to avoid layout distortion caused by very long custom field names --- app/assets/stylesheets/application.css | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 2ce5ea286..3dbfe4822 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -520,6 +520,7 @@ div.table-list.boards .table-list-cell.name {width: 30%;} #list-definition > div .field{ width: 160px; } +.query-columns { max-width: min(58vw, 500px); } .query-columns label { display:block; } @@ -529,6 +530,19 @@ div.table-list.boards .table-list-cell.name {width: 30%;} } .query-columns select { min-width:150px; + width: 100%; +} +.query-columns select option { + overflow: hidden; + text-overflow: ellipsis; +} +#query_form fieldset#options select#group_by, +#query-form fieldset#options select#query_group_by { + max-width: 500px; + width: 100%; +} +#query-form fieldset#sort select { + max-width:min(36vw, 500px); } .query-totals {text-align:right; margin-top:-2.3em; font-size: 93%;} @@ -762,6 +776,7 @@ fieldset#date-range p { margin: 2px 0 2px 0; } } .add-filter {width:35%; float:right; text-align: right; vertical-align: top;} +.add-filter select { max-width: 70%; } #issue_is_private_wrap {float:right; margin-right:1em;} .toggle-multiselect { margin-right:5px; cursor:pointer;} -- 2.25.1 From b6f25cf46d79f6bbf8c2ba0895b218168a8e6ed0 Mon Sep 17 00:00:00 2001 From: murin Date: Fri, 8 Nov 2024 10:51:32 +0300 Subject: Add tooltips for overflowing options of selects with available/selected columns in the query form Marks options of selects with the "js-overflow-to-tooltip" class. Class is used to enable the use of this mechanism in other places. If the content of an element, marked with the "js-overflow-to-tooltip" class, exits element boundaries and is clipped, a "title" attribute is set for the element with its text content as a value. If an element already has a "title" attribute with non-empty value, it remains untouched. --- app/assets/javascripts/application-legacy.js | 13 ++++++++++++- app/helpers/queries_helper.rb | 8 ++++++-- app/views/my/blocks/_issues.erb | 2 +- app/views/queries/_query_form.html.erb | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/application-legacy.js b/app/assets/javascripts/application-legacy.js index f7c1de95c..aef191017 100644 --- a/app/assets/javascripts/application-legacy.js +++ b/app/assets/javascripts/application-legacy.js @@ -128,7 +128,8 @@ function hideFieldset(el) { // columns selection function moveOptions(theSelFrom, theSelTo) { - $(theSelFrom).find('option:selected').detach().prop("selected", false).appendTo($(theSelTo)); + $(theSelFrom).find('option:selected').detach().prop("selected", false).appendTo($(theSelTo)). + filter('[title]').tooltip("close"); } function moveOptionUp(theSel) { @@ -1225,6 +1226,15 @@ function setupWikiTableSortableHeader() { } function setupHoverTooltips(container) { + $(".js-overflow-to-tooltip").each(function () { + const currentTitle = this.getAttribute('title'); + if ((this.scrollWidth > this.clientWidth || + this.scrollHeight > this.clientHeight) && + !currentTitle) { + this.setAttribute('title', this.textContent); + } + }); + $(container || 'body').find("[title]:not(.no-tooltip)").tooltip({ show: { delay: 400 @@ -1392,6 +1402,7 @@ function inlineAutoComplete(element) { button.click(function(e){ main.addClass("animate"); main.toggleClass('collapsedsidebar'); + setupHoverTooltips(); applyState(); e.preventDefault(); return false; diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index ca7168f27..2a53c98af 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -129,12 +129,16 @@ module QueriesHelper def query_available_inline_columns_options(query) (query.available_inline_columns - query.columns). - reject(&:frozen?).collect {|column| [column.caption, column.name]} + reject(&:frozen?).collect {|column| column_select_option(column)} end def query_selected_inline_columns_options(query) (query.inline_columns & query.available_inline_columns). - reject(&:frozen?).collect {|column| [column.caption, column.name]} + reject(&:frozen?).collect {|column| column_select_option(column)} + end + + def column_select_option(column) + [column.caption, column.name, {class: 'js-overflow-to-tooltip'}] end def render_query_columns_selection(query, options={}) diff --git a/app/views/my/blocks/_issues.erb b/app/views/my/blocks/_issues.erb index 33da64cd2..738579573 100644 --- a/app/views/my/blocks/_issues.erb +++ b/app/views/my/blocks/_issues.erb @@ -1,5 +1,5 @@
- <%= link_to_function sprite_icon('settings', l(:label_options)), "$('##{block}-settings').toggle();", :class => 'icon-only icon-settings', :title => l(:label_options) %> + <%= link_to_function sprite_icon('settings', l(:label_options)), "$('##{block}-settings').toggle(); setupHoverTooltips();", :class => 'icon-only icon-settings', :title => l(:label_options) %>

diff --git a/app/views/queries/_query_form.html.erb b/app/views/queries/_query_form.html.erb index 77094e16e..543f874ac 100644 --- a/app/views/queries/_query_form.html.erb +++ b/app/views/queries/_query_form.html.erb @@ -16,7 +16,7 @@ <% if @query.available_columns.any? %>