https://www.redmine.org/https://www.redmine.org/favicon.ico?16793021292019-10-21T07:35:14ZRedmineRedmine - Feature #32311: Filter Issues by multiple issue_id doesn't support space character or semicolon/dash as the separatorhttps://www.redmine.org/issues/32311?journal_id=944452019-10-21T07:35:14ZTaine Woo
<ul></ul><p>If the value of the issue_id is "1,2,3" in the filter, the query executes successfully.<br />If the value of the issue_id is "1 2 3" or "1 2 3" or "1, 2, 3", the query fails with message "•Issue is invalid"</p> Redmine - Feature #32311: Filter Issues by multiple issue_id doesn't support space character or semicolon/dash as the separatorhttps://www.redmine.org/issues/32311?journal_id=944492019-10-21T13:25:46ZTaine Woo
<ul></ul><p>app/models/query.rb</p>
<p>line 417, replace the "," as "\D" can use any non-numeric characters as separator.</p> Redmine - Feature #32311: Filter Issues by multiple issue_id doesn't support space character or semicolon/dash as the separatorhttps://www.redmine.org/issues/32311?journal_id=944502019-10-21T13:47:51ZTaine Woo
<ul></ul><p>/\A[+-]?\d+(\D[+-]?\d+)*\z/<br />digit separated by one non-digit</p>
<p>/\A[+-]?\d+(\D*\d+)*\z/<br />digit separated by any non-digit, easier for users.</p> Redmine - Feature #32311: Filter Issues by multiple issue_id doesn't support space character or semicolon/dash as the separatorhttps://www.redmine.org/issues/32311?journal_id=945072019-10-22T20:43:59ZMarius BĂLTEANU
<ul><li><strong>Tracker</strong> changed from <i>Defect</i> to <i>Feature</i></li></ul><p>It is the expected behaviour and I'm not sure that we should support more delimiters.</p> Redmine - Feature #32311: Filter Issues by multiple issue_id doesn't support space character or semicolon/dash as the separatorhttps://www.redmine.org/issues/32311?journal_id=947022019-11-01T14:52:26ZTaine Woo
<ul></ul><p>Marius BALTEANU wrote:</p>
<blockquote>
<p>It is the expected behaviour and I'm not sure that we should support more delimiters.</p>
</blockquote>
<p>Hi Marius,</p>
<p>Currently the regexp is quite strict, only support digits seperated by only comma, no other character is allowed, it's not a bug.<br />But according to my survey, most of the users will not want to input the Issue ID one by one manually.<br />Users will copy the IDs from tables such as excel, the data would be "1 2 3 ", the delimiter should be "tab", and if copied from csv, may be the delimiter would be space.</p>
<p>So if we loose the restrict, users may have better experience.</p> Redmine - Feature #32311: Filter Issues by multiple issue_id doesn't support space character or semicolon/dash as the separatorhttps://www.redmine.org/issues/32311?journal_id=954272019-12-25T08:35:29ZTaine Woo
<ul></ul><p>Here is my patch, case check added for integer.</p>
<pre><code class="ruby syntaxhl">
<span class="k">def</span> <span class="nf">validate_query_filters</span>
<span class="n">filters</span><span class="p">.</span><span class="nf">each_key</span> <span class="k">do</span> <span class="o">|</span><span class="n">field</span><span class="o">|</span>
<span class="k">if</span> <span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
<span class="k">case</span> <span class="n">type_for</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
<span class="k">when</span> <span class="ss">:integer</span>
<span class="k">case</span> <span class="n">operator_for</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
<span class="k">when</span> <span class="s2">"="</span>
<span class="c1">#add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/\A[+-]?\d+(\D[+-]?\d+)*\z/) }</span>
<span class="n">add_filter_error</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="ss">:invalid</span><span class="p">)</span> <span class="k">if</span> <span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">).</span><span class="nf">detect</span> <span class="p">{</span><span class="o">|</span><span class="n">v</span><span class="o">|</span> <span class="n">v</span><span class="p">.</span><span class="nf">present?</span> <span class="o">&&</span> <span class="o">!</span><span class="n">v</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">/\A[+-]?\d+(\D*\d+)*\z/</span><span class="p">)</span> <span class="p">}</span>
<span class="k">else</span>
<span class="n">add_filter_error</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="ss">:invalid</span><span class="p">)</span> <span class="k">if</span> <span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">).</span><span class="nf">detect</span> <span class="p">{</span><span class="o">|</span><span class="n">v</span><span class="o">|</span> <span class="n">v</span><span class="p">.</span><span class="nf">present?</span> <span class="o">&&</span> <span class="o">!</span><span class="n">v</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">/\A[+-]?\d+(,[+-]?\d+)*\z/</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">when</span> <span class="ss">:float</span>
<span class="n">add_filter_error</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="ss">:invalid</span><span class="p">)</span> <span class="k">if</span> <span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">).</span><span class="nf">detect</span> <span class="p">{</span><span class="o">|</span><span class="n">v</span><span class="o">|</span> <span class="n">v</span><span class="p">.</span><span class="nf">present?</span> <span class="o">&&</span> <span class="o">!</span><span class="n">v</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">/\A[+-]?\d+(\.\d*)?\z/</span><span class="p">)</span> <span class="p">}</span>
<span class="k">when</span> <span class="ss">:date</span><span class="p">,</span> <span class="ss">:date_past</span>
<span class="k">case</span> <span class="n">operator_for</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
<span class="k">when</span> <span class="s2">"="</span><span class="p">,</span> <span class="s2">">="</span><span class="p">,</span> <span class="s2">"<="</span><span class="p">,</span> <span class="s2">"><"</span>
<span class="n">add_filter_error</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="ss">:invalid</span><span class="p">)</span> <span class="k">if</span> <span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">).</span><span class="nf">detect</span> <span class="p">{</span><span class="o">|</span><span class="n">v</span><span class="o">|</span>
<span class="n">v</span><span class="p">.</span><span class="nf">present?</span> <span class="o">&&</span> <span class="p">(</span><span class="o">!</span><span class="n">v</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">/\A\d{4}-\d{2}-\d{2}(T\d{2}((:)?\d{2}){0,2}(Z|\d{2}:?\d{2})?)?\z/</span><span class="p">)</span> <span class="o">||</span> <span class="n">parse_date</span><span class="p">(</span><span class="n">v</span><span class="p">).</span><span class="nf">nil?</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">when</span> <span class="s2">">t-"</span><span class="p">,</span> <span class="s2">"<t-"</span><span class="p">,</span> <span class="s2">"t-"</span><span class="p">,</span> <span class="s2">">t+"</span><span class="p">,</span> <span class="s2">"<t+"</span><span class="p">,</span> <span class="s2">"t+"</span><span class="p">,</span> <span class="s2">"><t+"</span><span class="p">,</span> <span class="s2">"><t-"</span>
<span class="n">add_filter_error</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="ss">:invalid</span><span class="p">)</span> <span class="k">if</span> <span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">).</span><span class="nf">detect</span> <span class="p">{</span><span class="o">|</span><span class="n">v</span><span class="o">|</span> <span class="n">v</span><span class="p">.</span><span class="nf">present?</span> <span class="o">&&</span> <span class="o">!</span><span class="n">v</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">/^\d+$/</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">add_filter_error</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="ss">:blank</span><span class="p">)</span> <span class="k">unless</span>
<span class="c1"># filter requires one or more values</span>
<span class="p">(</span><span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">)</span> <span class="n">and</span> <span class="o">!</span><span class="n">values_for</span><span class="p">(</span><span class="n">field</span><span class="p">).</span><span class="nf">first</span><span class="p">.</span><span class="nf">blank?</span><span class="p">)</span> <span class="n">or</span>
<span class="c1"># filter doesn't require any value</span>
<span class="p">[</span><span class="s2">"o"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"!*"</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="s2">"t"</span><span class="p">,</span> <span class="s2">"ld"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">,</span> <span class="s2">"lw"</span><span class="p">,</span> <span class="s2">"l2w"</span><span class="p">,</span> <span class="s2">"m"</span><span class="p">,</span> <span class="s2">"lm"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"*o"</span><span class="p">,</span> <span class="s2">"!o"</span><span class="p">].</span><span class="nf">include?</span> <span class="n">operator_for</span><span class="p">(</span><span class="n">field</span><span class="p">)</span>
<span class="k">end</span> <span class="k">if</span> <span class="n">filters</span>
<span class="k">end</span>
</code></pre>