diff --git a/README.ja.md b/README.ja.md new file mode 100644 index 0000000..7207927 --- /dev/null +++ b/README.ja.md @@ -0,0 +1,135 @@ +# Redmine view customize plugin + +[Redmine](http://www.redmine.org)の画面をカスタマイズするためのプラグインです。 + +## 機能 + +条件に一致した画面に対して、JavaScript、CSSを埋め込むことで、画面をカスタマイズします。 + +## インストール方法 + +Redmineのプラグインディレクトリに、このリポジトリを`view_customize`としてクローンします。 + + cd {RAILS_ROOT}/plugins + git clone https://github.com/onozaty/redmine-view-customize.git view_customize + cd ../ + bundle exec rake redmine:plugins:migrate RAILS_ENV=production + +**注意: ディレクトリ名は`view_customize`とする必要があります。ディレクトリ名が異なると、プラグインの実行に失敗します。** + +## 使用方法 + +### 追加 + +プラグインをインストールすると、管理者メニューに「View customize」が追加されます。 + +![Screenshot of admin menu](screenshots/admin.en.png) + +「View customize」を押下すると、一覧画面に遷移します。 + +![Screenshot of list new](screenshots/list_new.en.png) + +「New view customize」を押下し、各種項目を入力します。 + +![Screenshot of new](screenshots/new.en.png) + +「Path pattern」は正規表現で指定します。ページのパスと一致すると、コードを挿入して実行します。 +以下は設定例です。 +* `.*` : 全てのページ +* `/issues$` : チケット一覧 +* `/issues/[0-9]+` : 個々のチケットの内容表示画面 + +「Insertion position」は、コードの挿入位置です。v1.2.0にて追加された項目になります。 +* 「Head of all pages」 : 全てのページのヘッダ部分。(v1.2.0より前のバージョンと同じ位置) +* 「Bottom of issue form」 : チケットの入力欄の下部。
+チケットの入力欄は、トラッカーやステータスを変えると再構成されますが、「Bottom of issue form」を指定しておくと再構成された際に再度実行されるので、入力欄に対する処理はこれを指定すると便利です。 +* 「Bottom of issue detail」 : チケットの詳細表示の下部。 + +該当ページにコードの挿入位置に該当する箇所が無かった場合、コードは埋め込まれません。たとえば、「Path pattern」で`.*`で全ページを指定しても、「Insertion position」に「Bottom of issue detail」を指定していると、チケットの詳細表示画面でしか実行されないことになります。 + +「Type」にてコードの種類(「JavaScript」または「CSS」)を選択し、「Code」に実際のコードを入力します。 + +「Comment」にはカスタマイズに対する概要を記載できます。ここで入力した内容は、一覧表示で表示されます。(Commentが入力されていればComment、Commentが入力されていない場合はCodeが一覧に表示) + +「Create」ボタン押下で新規カスタマイズの追加が完了です。 + +「Path pattern」に一致したページで指定のコードが実行され、画面がカスタマイズされるようになります。 + +![Screenshot of example](screenshots/example.en.png) + +### 編集/削除 + +![Screenshot of list edit](screenshots/list_edit.en.png) + +カスタマイズ一覧の番号を押下すると、カスタマイズ詳細画面へ遷移します。 + +![Screenshot of detail](screenshots/detail.en.png) + +「Delete」を押下すると削除できます。「Edit」を押下すると、編集画面へ遷移します。 + +入力項目は新規カスタマイズ作成時と同じです。 + +### 無効化 / プライベート + +「Enabled」のチェックを外すと、無効化することができます。「Private」をチェックすると、作成者のみに有効となります。 + +![Screenshot of enabled and private](screenshots/enable_private.en.png) + +まずは「Private」で動作確認したうえで、動作に問題なければ全体に公開するといった使い方ができます。 + +### ViewCustomize.context (JavaScript) + +JavaScriptのコードでは、`ViewCustomize.context`としてユーザやプロジェクトの情報にアクセスすることができます。 + +`ViewCustomize.context`の情報は下記のようなイメージです。 + +```javascript +ViewCustomize = { + "context": { + "user": { + "id": 1, + "login": "admin", + "admin": true, + "firstname": "Redmine", + "lastname": "Admin", + "groups": [ + {"id": 5, "name": "Group1"} + ], + "roles": [ // ユーザに紐づく全てのロール(全プロジェクト) + {"id": 4, "name": "Developer"}, + {"id": 6, "name": "RoleX"} + ], + "apiKey": "3dd35b5ad8456d90d21ef882f7aea651d367a9d8", + "customFields": [ + {"id": 1, "name": "[Custom field] Text", "value": "text"}, + {"id": 2, "name": "[Custom field] List", "value": ["B", "A"]}, + {"id": 3, "name": "[Custom field] Boolean", "value": "1"} + ] + }, + "project": { + "identifier": "project-a", + "name": "Project A", + "roles": [ // プロジェクト内でのロール + {"id": 6, "name": "RoleX"} + ] + }, + "issue": { + "id": 1 + } + } +} +``` + +例えばユーザのAPIキーにアクセスするには`ViewCustomize.context.user.apiKey`となります。 + +## 設定例 + +* [onozaty/redmine\-view\-customize\-scripts: Script list for "Redmine View Customize Plugin"](https://github.com/onozaty/redmine-view-customize-scripts) + +## サポートバージョン + +* Redmine 2.0.x 以降 + +## ライセンス + +このプラグインは [GNU General Public License](http://www.gnu.org/licenses/gpl-2.0.html) バージョン2またはそれ以降の条件で利用できます。 diff --git a/README.md b/README.md index 7abd65f..888c463 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,143 @@ -Redmine view customize plugin -=========================== +# Redmine view customize plugin This a plugin allows you to customize the view for the [Redmine](http://www.redmine.org). -Features ------------- +## Features -By adding JavaScript or CSS to the matched path, a screen is made customizable. +Customize the page by inserting JavaScript or CSS on the page that matched the condition. - -Installation ------------- +## Installation Install the plugin in your Redmine plugins directory, clone this repository as `view_customize`: - cd {RAILS_ROOT}/plugins - git clone https://github.com/onozaty/redmine-view-customize.git view_customize - cd ../ - bundle exec rake redmine:plugins:migrate RAILS_ENV=production +``` +cd {RAILS_ROOT}/plugins +git clone https://github.com/onozaty/redmine-view-customize.git view_customize +cd ../ +bundle exec rake redmine:plugins:migrate RAILS_ENV=production +``` **note: The directory name must be a `view_customize`. Directory name is different, it will fail to run the Plugin.** -Usage ------------- - -### Setting - -1. After you install the Plugin, "View customize" the administrator menu is added. -![Screenshot of admin menu](screenshots/admin.png) -![Screenshot of list](screenshots/list_new.png) -2. Add a new setting. -![Screenshot of new](screenshots/new.png) -3. Path pattern is specified with a regular expression. (ex. /issues/[0-9]+) -If there is a match with the path of the page, the code(JavaScript/StyleSheet) is executed. -![Screenshot of new path pattern](screenshots/new_pathpattern.png) -4. Input code. -![Screenshot of new JavaScript](screenshots/new_javascript.png) -![Screenshot of new StyleSheet](screenshots/new_stylesheet.png) -5. Matches the path, StyleSheet or JavaScrpt is embedded, the screen display is changed. -![Screenshot of view JavaScript](screenshots/view_javascript.png) -![Screenshot of view StyleSheet](screenshots/view_stylesheet.png) - -Supported versions ------------------- +## Usage + +### Add + +When installing the plugin, "View customize" is added to the administrator menu. + +![Screenshot of admin menu](screenshots/admin.en.png) + +Click "View customize" go to the list screen. + +![Screenshot of list new](screenshots/list_new.en.png) + +Click "New view customize" and enter items. + +![Screenshot of new](screenshots/new.en.png) + +"Path pattern" is specified by regular expression. If it matches the path of the page, insert the code and execute it. + +The following is an example. +* `.*` : All pages +* `/issues$` : Issue list +* `/issues/[0-9]+` : Issue detail page + +"Insertion position" is the code insertion position. It becomes item added in v1.2.0. + +* "Head of all pages" (The same position as the version before v1.2.0) +* "Bottom of issue form"
+Issue input fields are reconstructed when trackers or statuses are changed. If "Bottom of issue form" is specified, it will be executed again when reconstructed. +* "Bottom of issue detail" + +If there is no part corresponding to the insertion position of the code on the page, the code is not insert. +For example, even if you specify `.*` in "Path pattern", if "Bottom of issue detail" is specified for "Insertion position", it will be executed only on the issue detail page. + +In "Type", select the type of code ("JavaScript" or "CSS") and enter the actual code in "Code". + +For "Comment" you can put an overview on customization. The contents entered here are displayed in the list display. +When "Comment" is entered, "Comment" is displayed on the list. +If "Comment" is not entered, "Code" is displayed in the list. + +Addition is completed by clicking "Create" button. + +The specified code is executed on the page that matches "Path pattern", and the page will be customized. + +![Screenshot of example](screenshots/example.en.png) + +### Edit / Delete + +![Screenshot of list edit](screenshots/list_edit.en.png) + +When you click the number of the customize list, go to the detail page. + +![Screenshot of detail](screenshots/detail.en.png) + +You can delete it by clicking "Delete". + +Click "Edit" to switch to the edit page. +The input item is the same as when creating a new one. + +### Disable / Private + +You can disable it by unchecking "Enabled". If you check "Private", it will be enable only for the author. + +![Screenshot of enabled and private](screenshots/enable_private.en.png) + +If you check the operation with "Private" and there is no problem in operation, it will be good to release it to the all. + +### ViewCustomize.context (JavaScript) + +You can access information on users and projects using `ViewCustomize.context`. + +`ViewCustomize.context` is as follows. + +```javascript +ViewCustomize = { + "context": { + "user": { + "id": 1, + "login": "admin", + "admin": true, + "firstname": "Redmine", + "lastname": "Admin", + "groups": [ + {"id": 5, "name": "Group1"} + ], + "roles": [ // All roles associated with users (all projects) + {"id": 4, "name": "Developer"}, + {"id": 6, "name": "RoleX"} + ], + "apiKey": "3dd35b5ad8456d90d21ef882f7aea651d367a9d8", + "customFields": [ + {"id": 1, "name": "[Custom field] Text", "value": "text"}, + {"id": 2, "name": "[Custom field] List", "value": ["B", "A"]}, + {"id": 3, "name": "[Custom field] Boolean", "value": "1"} + ] + }, + "project": { + "identifier": "project-a", + "name": "Project A", + "roles": [ // Roles in the project + {"id": 6, "name": "RoleX"} + ] + }, + "issue": { + "id": 1 + } + } +} +``` + +For example, to access the user's API key is `ViewCustomize.context.user.apiKey`. + +## Examples + +* [onozaty/redmine\-view\-customize\-scripts: Script list for "Redmine View Customize Plugin"](https://github.com/onozaty/redmine-view-customize-scripts) + +## Redmine 2.0.x or later * Redmine 2.0.x or later -License -------- +## License The plugin is available under the terms of the [GNU General Public License](http://www.gnu.org/licenses/gpl-2.0.html), version 2 or later. diff --git a/app/controllers/view_customizes_controller.rb b/app/controllers/view_customizes_controller.rb index 89113bc..d1da765 100644 --- a/app/controllers/view_customizes_controller.rb +++ b/app/controllers/view_customizes_controller.rb @@ -6,8 +6,13 @@ class ViewCustomizesController < ApplicationController before_filter :require_admin before_filter :find_view_customize, :except => [:index, :new, :create] + helper :sort + include SortHelper + def index - @view_customizes = ViewCustomize.all + sort_init 'id', 'desc' + sort_update %w(id path_pattern insertion_position customize_type code comments is_enabled is_private) + @view_customizes = ViewCustomize.all.order(sort_clause) end def new diff --git a/app/models/view_customize.rb b/app/models/view_customize.rb index 41a4006..95b39ba 100644 --- a/app/models/view_customize.rb +++ b/app/models/view_customize.rb @@ -1,5 +1,3 @@ - - class ViewCustomize < ActiveRecord::Base unloadable @@ -14,28 +12,46 @@ class ViewCustomize < ActiveRecord::Base attr_protected :id - TYPE_JAVASCRIPT = 1 - TYPE_STYLESHEET = 2 + TYPE_JAVASCRIPT = "javascript" + TYPE_CSS = "css" @@customize_types = { - "JavaScript" => TYPE_JAVASCRIPT, - "StyleSheet" => TYPE_STYLESHEET + :label_javascript => TYPE_JAVASCRIPT, + :label_css => TYPE_CSS + } + + INSERTION_POSITION_HTML_HEAD = "html_head" + INSERTION_POSITION_ISSUE_FORM = "issue_form" + INSERTION_POSITION_ISSUE_SHOW = "issue_show" + + @@insertion_positions = { + :label_insertion_position_html_head => INSERTION_POSITION_HTML_HEAD, + :label_insertion_position_issue_form => INSERTION_POSITION_ISSUE_FORM, + :label_insertion_position_issue_show => INSERTION_POSITION_ISSUE_SHOW } def customize_types @@customize_types end - def customize_type_name + def customize_type_label @@customize_types.key(customize_type) end + def insertion_positions + @@insertion_positions + end + + def insertion_position_label + @@insertion_positions.key(insertion_position) + end + def is_javascript? customize_type == TYPE_JAVASCRIPT end - def is_stylesheet? - customize_type == TYPE_STYLESHEET + def is_css? + customize_type == TYPE_CSS end def available?(user=User.current) diff --git a/app/views/view_customizes/_form.html.erb b/app/views/view_customizes/_form.html.erb index ae718ec..223bc85 100644 --- a/app/views/view_customizes/_form.html.erb +++ b/app/views/view_customizes/_form.html.erb @@ -8,14 +8,26 @@ <%= l(:text_path_pattern_match_info) %>

+

+ <%= form.select :insertion_position, + options_for_select( + @view_customize.insertion_positions.map {|key, val| [l(key), val]}, + :selected => @view_customize.insertion_position), + :required => true %> +

<%= form.select :customize_type, - options_for_select(@view_customize.customize_types, :selected => @view_customize.customize_type), - :required => true %> + options_for_select( + @view_customize.customize_types.map {|key, val| [l(key), val]}, + :selected => @view_customize.customize_type), + :required => true %>

<%= form.text_area :code, - :required => true, :rows => 12 %> + :required => true, :rows => 12 %> +

+

+ <%= form.text_field :comments, :size => 100 %>

<%= form.check_box :is_enabled %> diff --git a/app/views/view_customizes/_header.html.erb b/app/views/view_customizes/_header.html.erb deleted file mode 100644 index 1747646..0000000 --- a/app/views/view_customizes/_header.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= stylesheet_link_tag "view_customize.css", :plugin => 'view_customize' %> diff --git a/app/views/view_customizes/edit.html.erb b/app/views/view_customizes/edit.html.erb index 533d690..9a4878c 100644 --- a/app/views/view_customizes/edit.html.erb +++ b/app/views/view_customizes/edit.html.erb @@ -1,5 +1,3 @@ -<%= render :partial => 'view_customizes/header' %> - <%= title [l(:label_view_customize_plural), view_customizes_path], @view_customize.id %> <%= labelled_form_for :view_customize, @view_customize, diff --git a/app/views/view_customizes/index.html.erb b/app/views/view_customizes/index.html.erb index 3d23c8c..bc854a6 100644 --- a/app/views/view_customizes/index.html.erb +++ b/app/views/view_customizes/index.html.erb @@ -1,5 +1,3 @@ -<%= render :partial => 'view_customizes/header' %> -

<%= link_to l(:label_view_customizes_new), new_view_customize_path, :class => 'icon icon-add' %> @@ -11,17 +9,16 @@

<%= l(:label_no_data) %>

<% else %> - +
- - - - - - - + <%= sort_header_tag('id', :caption => '#') %> + <%= sort_header_tag('path_pattern', :caption => l(:field_path_pattern)) %> + <%= sort_header_tag('insertion_position', :caption => l(:field_insertion_position)) %> + <%= sort_header_tag('customize_type', :caption => l(:field_customize_type)) %> + <%= sort_header_tag('comments', :caption => l(:field_comments) + ' / ' + l(:field_code)) %> + <%= sort_header_tag('is_private', :caption => l(:field_is_private)) %> @@ -30,11 +27,10 @@ - - - + + + - <% end %> diff --git a/app/views/view_customizes/new.html.erb b/app/views/view_customizes/new.html.erb index 2947593..4abe28b 100644 --- a/app/views/view_customizes/new.html.erb +++ b/app/views/view_customizes/new.html.erb @@ -1,5 +1,3 @@ -<%= render :partial => 'view_customizes/header' %> - <%= title [l(:label_view_customize_plural), view_customizes_path], l(:label_view_customizes_new) %> <%= labelled_form_for :view_customize, @view_customize, diff --git a/app/views/view_customizes/show.html.erb b/app/views/view_customizes/show.html.erb index dc87158..a6d2118 100644 --- a/app/views/view_customizes/show.html.erb +++ b/app/views/view_customizes/show.html.erb @@ -1,4 +1,3 @@ -<%= render :partial => 'view_customizes/header' %> <%= stylesheet_link_tag "scm" %>
@@ -18,14 +17,22 @@
+ + + + - + + @view_customize.code, @view_customize.is_javascript? ? :js : :css) %> + + + + diff --git a/assets/images/view_customize.png b/assets/images/view_customize.png new file mode 100644 index 0000000..106f5aa Binary files /dev/null and b/assets/images/view_customize.png differ diff --git a/assets/stylesheets/view_customize.css b/assets/stylesheets/view_customize.css index ce10904..509cccf 100644 --- a/assets/stylesheets/view_customize.css +++ b/assets/stylesheets/view_customize.css @@ -1,24 +1,31 @@ -table.list td.code, table.list td.path { +table.view_customize.list td.path, table.view_customize.list td.comments { text-align: left; + word-break: break-word; + overflow-wrap: break-word; + word-wrap : break-word; } -table.list td.id { - min-width: 40px; +table.view_customize.list td.id { + padding-left: 5px; } -table.list tr.disable { +table.view_customize.list td.insertion_position { + white-space: nowrap; +} + +table.view_customize.list tr.disable { color: #aaaaaa; } -table.list tr.private { +table.view_customize.list tr.private { font-style: italic; } -table.view_customize { +table.view_customize.box { width: 100%; } -table.view_customize th { +table.view_customize.box th { text-align: right; vertical-align: top; width: 10%; @@ -26,11 +33,11 @@ table.view_customize th { white-space: nowrap; } -table.view_customize td { +table.view_customize.box td { vertical-align: top; } -table.view_customize td pre { +table.view_customize.box td pre { margin: 0; padding: 2px 4px; background-color: #FFFFFF; @@ -42,6 +49,10 @@ textarea#view_customize_code { width: 95%; } -#admin-menu a.view_customize { - background-image: url("../images/server_key.png"); +input#view_customize_comments { + width: 95%; +} + +.icon-view_customize { + background-image: url("../images/view_customize.png"); } diff --git a/config/locales/en.yml b/config/locales/en.yml index dd7db9b..413a775 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3,11 +3,18 @@ en: label_view_customize: "View customize" label_view_customize_plural: "View customizes" label_view_customizes_new: "New view customize" + label_javascript: "JavaScript" + label_css: "CSS" + label_insertion_position_html_head: "Head of all pages" + label_insertion_position_issue_form: "Bottom of issue form" + label_insertion_position_issue_show: "Bottom of issue detail" field_path_pattern: "Path pattern" + field_insertion_position: "Insertion position" field_customize_type: "Type" field_code: "Code" + field_comments: "Comment" field_is_private: "Private" field_is_enabled: "Enabled" field_author: "Author" text_path_pattern_info: "Path pattern is specified with a regular expression. (ex. /issues/[0-9]+)" - text_path_pattern_match_info: "If there is a match with the path of the page, the following code is executed." + text_path_pattern_match_info: "If there is a match with the path of the page, insert the following code and execute it." diff --git a/config/locales/ja.yml b/config/locales/ja.yml new file mode 100644 index 0000000..b71e9ec --- /dev/null +++ b/config/locales/ja.yml @@ -0,0 +1,19 @@ +ja: + label_view_customize: "表示のカスタマイズ" + label_view_customize_plural: "表示のカスタマイズ" + label_view_customizes_new: "新しい表示のカスタマイズ" + label_javascript: "JavaScript" + label_css: "CSS" + label_insertion_position_html_head: "全てのページのヘッダ" + label_insertion_position_issue_form: "チケット入力欄の下" + label_insertion_position_issue_show: "チケット詳細の下" + field_path_pattern: "パスのパターン" + field_insertion_position: "挿入位置" + field_customize_type: "種別" + field_code: "コード" + field_comments: "コメント" + field_is_private: "プライベート" + field_is_enabled: "有効" + field_author: "作成者" + text_path_pattern_info: "パスのパターンは正規表現で指定します。 (例 /issues/[0-9]+)" + text_path_pattern_match_info: "ページのパスが一致した場合、以下のコードを挿入し、実行します。" diff --git a/db/migrate/003_add_insertion_position_to_view_customizes.rb b/db/migrate/003_add_insertion_position_to_view_customizes.rb new file mode 100644 index 0000000..b7bed77 --- /dev/null +++ b/db/migrate/003_add_insertion_position_to_view_customizes.rb @@ -0,0 +1,27 @@ +class AddInsertionPositionToViewCustomizes < ActiveRecord::Migration + def up + add_column :view_customizes, :insertion_position, :string, :null => false, :default => "html_head" + + rename_column :view_customizes, :customize_type, :customize_type_old + add_column :view_customizes, :customize_type, :string, :null => false, :default => "javascript" + ActiveRecord::Base.connection.execute( + "UPDATE view_customizes SET customize_type = 'css' WHERE customize_type_old = 2") + remove_column :view_customizes, :customize_type_old + + change_column_null :view_customizes, :path_pattern, false + change_column_null :view_customizes, :code, false + end + + def down + change_column_null :view_customizes, :path_pattern, true + change_column_null :view_customizes, :code, true + + rename_column :view_customizes, :customize_type, :customize_type_new + add_column :view_customizes, :customize_type, :integer, :default => 1 + ActiveRecord::Base.connection.execute( + "UPDATE view_customizes SET customize_type = 1 WHERE customize_type_new = 'css'") + remove_column :view_customizes, :customize_type_new + + remove_column :view_customizes, :insertion_position + end +end diff --git a/db/migrate/004_add_comments_to_view_customizes.rb b/db/migrate/004_add_comments_to_view_customizes.rb new file mode 100644 index 0000000..e14024e --- /dev/null +++ b/db/migrate/004_add_comments_to_view_customizes.rb @@ -0,0 +1,9 @@ +class AddCommentsToViewCustomizes < ActiveRecord::Migration + def up + add_column :view_customizes, :comments, :string, :null => true + end + + def down + remove_column :view_customizes, :comments + end +end diff --git a/init.rb b/init.rb index dfd84c1..39e702b 100644 --- a/init.rb +++ b/init.rb @@ -1,17 +1,17 @@ -require_dependency 'view_customize/view_layouts_base_html_head_hook' +require_dependency 'view_customize/view_hook' Redmine::Plugin.register :view_customize do name 'View Customize plugin' author 'onozaty' description 'View Customize plugin for Redmine' - version '1.1.4' + version '1.2.0' url 'https://github.com/onozaty/redmine-view-customize' author_url 'https://github.com/onozaty' menu :admin_menu, :view_customizes, { :controller => 'view_customizes', :action => 'index' }, :caption => :label_view_customize, - :html => { :class => 'settings'}, + :html => { :class => 'icon icon-view_customize'}, :if => Proc.new { User.current.admin? } end diff --git a/lib/view_customize/view_hook.rb b/lib/view_customize/view_hook.rb new file mode 100644 index 0000000..85df8f7 --- /dev/null +++ b/lib/view_customize/view_hook.rb @@ -0,0 +1,100 @@ +module RedmineViewCustomize + class ViewHook < Redmine::Hook::ViewListener + def view_layouts_base_html_head(context={}) + + path = context[:request].path_info; + + html = "\n\n" + html << stylesheet_link_tag("view_customize", plugin: "view_customize") + html << "" + + html << create_view_customize_html(path, ViewCustomize::INSERTION_POSITION_HTML_HEAD) + + return html + end + + def view_issues_form_details_bottom(context={}) + + return create_view_customize_html(context[:request].path_info, ViewCustomize::INSERTION_POSITION_ISSUE_FORM) + end + + def view_issues_show_details_bottom(context={}) + + html = "" + + html << create_view_customize_html(context[:request].path_info, ViewCustomize::INSERTION_POSITION_ISSUE_SHOW) + + return html + end + + private + + def create_view_customize_html(path, insertion_position) + + view_customize_html_parts = match_customize(path, insertion_position).map {|item| + to_html(item) + } + return view_customize_html_parts.join("\n").html_safe + + end + + def match_customize(path, insertion_position) + + ViewCustomize.all.select {|item| + item.available? \ + && item.insertion_position == insertion_position \ + && path =~ Regexp.new(item.path_pattern) + } + end + + def to_html(view_customize) + + html = "\n" + + if view_customize.is_javascript? + html << "" + elsif view_customize.is_css? + html << "" + end + + return html + end + + def create_view_customize_context(view_hook_context) + + user = User.current + context = { + "user" => { + "id" => user.id, + "login" => user.login, + "admin" => user.admin?, + "firstname" => user.firstname, + "lastname" => user.lastname, + "groups" => user.groups.map {|group| { "id" => group.id, "name" => group.name }}, + "roles" => user.roles.map {|role| { "id" => role.id, "name" => role.name }}, + "apiKey" => (user.api_token.value unless user.api_token.nil?), + "customFields" => user.custom_field_values.map {|field| { "id" => field.custom_field.id, "name" => field.custom_field.name, "value" => field.value }} + } + } + + project = view_hook_context[:project] + if project + context["project"] = { + "identifier" => project.identifier, + "name" => project.name, + "roles" => user.roles_for_project(project).map {|role| { "id" => role.id, "name" => role.name }} + } + end + + return context + end + end +end diff --git a/lib/view_customize/view_layouts_base_html_head_hook.rb b/lib/view_customize/view_layouts_base_html_head_hook.rb deleted file mode 100644 index b29875d..0000000 --- a/lib/view_customize/view_layouts_base_html_head_hook.rb +++ /dev/null @@ -1,39 +0,0 @@ -module RedmineViewCustomize - class ViewLayoutsBaseHtmlHeadHook < Redmine::Hook::ViewListener - def view_layouts_base_html_head(context={}) - - view_customize_html_parts = match_customize(context[:request].path_info).map {|item| - html(item) - } - - return "\n" + - view_customize_html_parts.join("\n").html_safe - end - - private - - def match_customize(path) - - ViewCustomize.all.select {|item| - item.available? && path =~ Regexp.new(item.path_pattern) - } - end - - def html(view_customize) - - html = "\n" - - if view_customize.is_javascript? then - html << "" - elsif view_customize.is_stylesheet? then - html << "" - end - - return html - end - end -end diff --git a/screenshots/admin.en.png b/screenshots/admin.en.png new file mode 100644 index 0000000..36f0b4d Binary files /dev/null and b/screenshots/admin.en.png differ diff --git a/screenshots/admin.png b/screenshots/admin.png deleted file mode 100644 index ad910ad..0000000 Binary files a/screenshots/admin.png and /dev/null differ diff --git a/screenshots/detail.en.png b/screenshots/detail.en.png new file mode 100644 index 0000000..98fa619 Binary files /dev/null and b/screenshots/detail.en.png differ diff --git a/screenshots/enable_private.en.png b/screenshots/enable_private.en.png new file mode 100644 index 0000000..117803f Binary files /dev/null and b/screenshots/enable_private.en.png differ diff --git a/screenshots/example.en.png b/screenshots/example.en.png new file mode 100644 index 0000000..8bb3a26 Binary files /dev/null and b/screenshots/example.en.png differ diff --git a/screenshots/list_edit.en.png b/screenshots/list_edit.en.png new file mode 100644 index 0000000..a69e47d Binary files /dev/null and b/screenshots/list_edit.en.png differ diff --git a/screenshots/list_new.en.png b/screenshots/list_new.en.png new file mode 100644 index 0000000..0d33473 Binary files /dev/null and b/screenshots/list_new.en.png differ diff --git a/screenshots/list_new.png b/screenshots/list_new.png deleted file mode 100644 index 0aa3492..0000000 Binary files a/screenshots/list_new.png and /dev/null differ diff --git a/screenshots/new.en.png b/screenshots/new.en.png new file mode 100644 index 0000000..067a334 Binary files /dev/null and b/screenshots/new.en.png differ diff --git a/screenshots/new.png b/screenshots/new.png deleted file mode 100644 index 714f441..0000000 Binary files a/screenshots/new.png and /dev/null differ diff --git a/screenshots/new_javascript.png b/screenshots/new_javascript.png deleted file mode 100644 index 093e66f..0000000 Binary files a/screenshots/new_javascript.png and /dev/null differ diff --git a/screenshots/new_pathpattern.png b/screenshots/new_pathpattern.png deleted file mode 100644 index bb7560a..0000000 Binary files a/screenshots/new_pathpattern.png and /dev/null differ diff --git a/screenshots/new_stylesheet.png b/screenshots/new_stylesheet.png deleted file mode 100644 index 071f8b3..0000000 Binary files a/screenshots/new_stylesheet.png and /dev/null differ diff --git a/screenshots/view_javascript.png b/screenshots/view_javascript.png deleted file mode 100644 index d280f39..0000000 Binary files a/screenshots/view_javascript.png and /dev/null differ diff --git a/screenshots/view_stylesheet.png b/screenshots/view_stylesheet.png deleted file mode 100644 index 2b287b6..0000000 Binary files a/screenshots/view_stylesheet.png and /dev/null differ
#<%=h l(:field_path_pattern) %><%=h l(:field_customize_type) %><%=h l(:field_code) %><%=h l(:field_is_enabled) %><%=h l(:field_is_private) %>
<%= link_to view_customize.id, view_customize_path(view_customize.id) %> <%=h view_customize.path_pattern %><%=h view_customize.customize_type_name %><%=h truncate(view_customize.code, :length => 80) %><%=h view_customize.is_enabled ? l(:general_text_yes) : l(:general_text_no) %><%=h l(view_customize.insertion_position_label) %><%=h l(view_customize.customize_type_label) %><%=h view_customize.comments.present? ? view_customize.comments : truncate(view_customize.code, :length => 80) %> <%=h view_customize.is_private ? l(:general_text_yes) : l(:general_text_no) %>
<%=h l(:field_path_pattern) %>: <%=h @view_customize.path_pattern %>
<%=h l(:field_insertion_position) %>:<%=h l(@view_customize.insertion_position_label) %>
<%=h l(:field_customize_type) %>:<%=h @view_customize.customize_type_name %><%=h l(@view_customize.customize_type_label) %>
<%=h l(:field_code) %>: <%= highlight_by_language( - @view_customize.code, @view_customize.customize_type == 1 ? :js : :css) %>
<%=h l(:field_comments) %>:<%=h @view_customize.comments %>
<%=h l(:field_is_enabled) %>: