Project

General

Profile

Actions

QA #1156

open

attachment 書式で表記した添付ファイルの隣にダウンロードリンクが表示できないか

Added by I Iwadara 8 months ago. Updated 10 days ago.

Status:
新規
Priority:
通常
Assignee:
Category:
-
Target version:
-
Start date:
08/26/2020
Due date:
% Done:

0%

Estimated time:

Description

■現象/要望

Redmine 3.4.0 より入った以下の変更により、
attachment 書式で表記した添付ファイルもダウンロードではなく、プレビュー動作となってしまった。
http://blog.redmine.jp/articles/updates/2017/06/
Feature #25988: 添付ファイルをクリックしたときの動作をダウンロードからプレビューに変更

長い注記コメントや Wiki を辿る際、Word や Excel ファイルなど
プレビュー対応していないファイルタイプに対しても上記プレビュー動作が働くことから、
「プレビューできない画面表示」→「ダウンロードを選択」という 2 ステップ必要となり
リモート会議等での進行で都度 2 ステップかかることにテンポの悪さを感じている。

■解決策

(案1)
attachment 書式で表記した添付ファイルの隣にダウンロードリンクを併記できないか
→ 1ステップでプレビュー不要なファイルはダウンロードリンクにより開く

ViewCustomizeによる対応
https://redmine.tokyo/issues/1156#note-9
https://redmine.tokyo/issues/1156#note-10

(案2)
Officeファイル、画像(現プレビュー)共に、ファイルダウンロードにする手抜き改造
https://redmine.tokyo/issues/1156#note-5

■対応状況

ViewCustomize,パッチによる対応策有

■補足

とくになし

Actions #1

Updated by I Iwadara 8 months ago

  • Description updated (diff)
Actions #2

Updated by I Iwadara 8 months ago

  • Description updated (diff)
Actions #3

Updated by 奈良 裕記 8 months ago

「このファイルはダウンロードできません。ダウンロードしてください。」
と表示しているのだから、プレビュー対象外であることは把握している。

プレビュー対象外の場合には、3.3までと同様に直接ダウンロードしても良いのではと思いますね。

運用上で回避可能な些細な問題とも言えますが、
Office系ファイルの扱いに対する姿勢の違いを感じます。
実質的にWindows-Officeしかいない世界だと、XLSXなどはそのまま有無を言わさず起動すれば良い訳で。

Actions #4

Updated by I Iwadara 8 months ago

奈良 裕記 さんは #note-3 で書きました:

プレビュー対象外の場合には、3.3までと同様に直接ダウンロードしても良いのではと思いますね。

(案2) として、ご提案いただいた上記対応も適切と思います。
現状ですとプレビュー対象外画面を都度挟む必然性を感じておりません。

Actions #5

Updated by 奈良 裕記 8 months ago

Officeファイル、画像(現プレビュー)共に、ファイルダウンロードにする手抜き改造

サンプル→ http://demo1.unofficial-redmine.org/redmine/issues/61337

app/views/attachments/_links.html.erb

下記の最初の link_to_attachmentの箇所を変更

<% for attachment in attachments %>
<tr>
  <td>
    <%= link_to_attachment attachment, class: 'icon icon-attachment' -%>
    <span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
    <%= link_to_attachment attachment, class: 'icon-only icon-download', title:
l(:button_download), download: true -%>
  </td>

(現行) <%= link_to_attachment attachment, class: 'icon icon-attachment' ->
(改造) <
= link_to_attachment attachment, class: 'icon icon-attachment',download: true -%>

Actions #6

Updated by 奈良 裕記 8 months ago

関連ソース

チケット表示の親分

app/views/issues/show.html.erb

<% if @issue.attachments.any? %>
  <hr />
  <p><strong><%=l(:label_attachment_plural)%></strong></p>
  <%= link_to_attachments @issue, :thumbnails => true %>
<% end %>

helpers/attachments_helper.rb

  # Displays view/delete links to the attachments of the given object
  # Options:
  #   :author -- author names are not displayed if set to false
  #   :thumbails -- display thumbnails if enabled in settings
  def link_to_attachments(container, options = {})
    options.assert_valid_keys(:author, :thumbnails)
    attachments =
      if container.attachments.loaded?
        container.attachments
      else
        container.attachments.preload(:author).to_a
      end
    if attachments.any?
      options = {
        :editable => container.attachments_editable?,
        :deletable => container.attachments_deletable?,
        :author => true
      }.merge(options)
      render :partial => 'attachments/links',
        :locals => {
          :container => container,
          :attachments => attachments,
          :options => options,
          :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)
        }
    end

app/views/attachments/_links.html.erb

<% for attachment in attachments %>
<tr>
  <td>
    <%= link_to_attachment attachment, class: 'icon icon-attachment' -%>
    <span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
    <%= link_to_attachment attachment, class: 'icon-only icon-download', title:
l(:button_download), download: true -%>
  </td>
  <td><%= attachment.description unless attachment.description.blank? %></td>
  <td>

helpers/application_helper.rb

  # Generates a link to an attachment.
  # Options:
  # * :text - Link text (default to attachment filename)
  # * :download - Force download (default: false)
  def link_to_attachment(attachment, options={})
    text = options.delete(:text) || attachment.filename
    if options.delete(:download)
      route_method = :download_named_attachment_url
      options[:filename] = attachment.filename
    else
      route_method = :attachment_url
      # make sure we don't have an extraneous :filename in the options
      options.delete(:filename)
    end
    html_options = options.slice!(:only_path, :filename)
    options[:only_path] = true unless options.key?(:only_path)
    url = send(route_method, attachment, options)
    link_to text, url, html_options
  end


Actions #7

Updated by 奈良 裕記 8 months ago

ここからは、実際に画面上で押された後の処理

用語は下記の通り
label_no_preview_alternative_html: このファイルはプレビューできません。 %{link} してください。
label_no_preview: このファイルはプレビューできません
label_no_preview_download: ダウンロード

app/views/attachments/other.html.erb:

<%= render :layout => 'layouts/file' do %>

  <% kind = if @attachment.is_video?
       'video'
     elsif @attachment.is_audio?
       'audio'
     end %>

  <%= render :partial => "common/other",
             :locals => {
               :kind => kind,
               :path => download_named_attachment_url(@attachment,
                                                      @attachment.filename),
               :download_link => link_to_attachment(
                                   @attachment,
                                   :text => l(:label_no_preview_download),
                                   :download => true,
                                   :class => 'icon icon-download'
                                 )
             } %>
<% end %>

app/views/common/_other.html.erb
(officeファイルの場合の処理抜粋、videoもaudioもelseも全部同じ処理に見えるが。。)

    <%= render partial: 'common/no_preview', locals: { download_link: download_link } %>

app/views/common/no_preview.html.erb

<p class="nodata">
  <% if download_link %>
    <%= t(:label_no_preview_alternative_html, link: download_link) %>
  <% else %>
    <%= l(:label_no_preview) %>
  <% end %>
</p>

Actions #8

Updated by I Iwadara 8 months ago

奈良 裕記 さんは #note-5 で書きました:

下記の最初の link_to_attachmentの箇所を変更

この変更を反映すると添付ファイルとして表示されいる箇所は強制的なダウンロードリンクとなりましたが、
attachment:"file.xlsx" 書式で表記した内容は変化ありませんでした。

今回解決したい課題は attachment:"file.xlsx" 書式で表記した箇所に対して
ダウンロード選択できないこと、であるため
もう少しこちらでも調査してみたいと思います。

Actions #9

Updated by Kawai takashi 8 months ago

View Customize Pluginを使って、以下のようにするのはどうでしょう。

/*
パスのパターン:/issues/[0-9]+
挿入位置:全ページのヘッダ
種別:JavaScript
*/

$(function() {
    notprevfile();

    let iconaddflg;
    $(document).off('click', '#history input[type="submit"]');
    $(document).on('click', '#history input[type="submit"]', function() {
        iconaddflg = false;
        $('.add-download').remove();
        $(document).ajaxStop(function() {
            if (iconaddflg == false) {
                iconaddflg = true;
                notprevfile();
            }
        })
    })
})

function notprevfile() {
    const mimeTypesnotprev = { //プレビュー表示させたくない拡張子を登録してください
        "xls": "notprev/xls",
        "xlsx": "notprev/xlsx",
        "doc": "notprev/doc",
        "docx": "notprev/docx",
        "tif": "notprev/tif",
        "tiff": "notprev/tif" 
    }
    $('p a.attachment, p a.external, a.icon-attachment, #history .details a:not(.icon-download)').each(function() {
        const href = $(this).attr('href')
        const ext = href.split('/').pop().split('.').pop();
        const mime = mimeTypesnotprev[ext];
        if (/^notprev\//.test(mime)) {
            const itemclass = $(this).attr('class');
            const src = href.replace("/attachments/", "/attachments/download/");
            $(this).attr('href', src);
            $(this).attr('title', "このファイルはプレビューできません。 クリックでダウンロードします。");
            if (itemclass === "attachment" || itemclass === "external") {
                const text = $(this).text();
                $(this).after(' <a class="icon-only icon-download add-download" title="ダウンロード" href="' + src + '"> ' + text + '</a>');
            }
        }
    })
}
Actions #10

Updated by I Iwadara 8 months ago

Kawai takashi さんは #note-9 で書きました:

View Customize Pluginを使って、以下のようにするのはどうでしょう。

こちらの環境(Redmine 4.1.1)でいただいた View Customize の適用をしたところ、
うまく動作しませんでした。こちらで調査したところ、
拡張子の特定部が期待通りの動きとなりませんでした。

以下の変更を施すことで、所望の効果が得られることが確認できました。

-         const ext = href.split('/').pop().split('.').pop();
+         const ext = $(this).text().split('/').pop().split('.').pop();

また、本来の希望としては「attachment:"file.xlsx" 書式で記載した箇所のみダウンロード選択できるようにする」
であったため、適用範囲は p a.attachment に絞る形としました。

以上により、所望の動作が実現できました。
情報いただき、ありがとうございました。

Actions #11

Updated by 奈良 裕記 8 months ago

Kawai takashiさん、いつもありがとうございます。

こういった内容は、ViewCustomizeで対応するのがスマートですね。

Actions #12

Updated by Kawai takashi 8 months ago

今回のように、「attachment:"file.xlsx" 書式で表記した内容」の場合は、自サーバ上のファイルなので問題ないと思うのですが、「a.external」で外部サーバへのリンクを張っている場合は、直接ダウンロードしてしまうのはちょっと怖い気がします。

個別の問題で、すぐにでも使いたいという場合はViewCustomizeで対応するのは手軽で良いです。ですが、Redmine本体のほうで共通で対応すべきこともあると思います。ファイルのプレビューの仕方は本体のほうで対応してもらいたいですね。

Actions #13

Updated by I Iwadara 8 months ago

Kawai takashi さんは #note-12 で書きました:

ですが、Redmine本体のほうで共通で対応すべきこともあると思います。ファイルのプレビューの仕方は本体のほうで対応してもらいたいですね。

こちらの見解について、私も賛同します。

Actions #14

Updated by 奈良 裕記 8 months ago

本件は、本家でも考慮して欲しい内容ですね。

出雲の神のご意見を聞きたいところ。。

Actions #15

Updated by 奈良 裕記 8 months ago

  • Description updated (diff)
Actions #16

Updated by 奈良 裕記 8 months ago

こんなアンケート実施したらどうなるかな。。

Redmine添付Officeファイルのプレビュー表示

Redmineの添付ファイル表示時動作、画像ファイルは直接プレビューできるが、
Officeファイルは、プレビュー不可/ダウンロード選択が必要になり冗長です。(Redmine3.4以降)
ご意見お聞かせください。

・現状のままで良い(Officeファイルはプレビュー不可表示を挟みダウンロード画面表示,3.4以降の動作)
・Officeファイルの場合は直接ダウンロード画面に移行して欲しい
・全部ダウンロードで良い。(3.3までの動作)
・Officeファイルはダウンロード操作も無しで直接起動して欲しい

Actions #17

Updated by 奈良 裕記 10 days ago

  • Description updated (diff)
Actions

Also available in: Atom PDF