From 645c2bbefc96f38bc4d212e4f49e022ab98e6ffb Mon Sep 17 00:00:00 2001 From: uu59 Date: Tue, 25 Nov 2014 17:43:11 +0900 Subject: [PATCH 01/11] Refactor: Config#config -> Config#fl_config --- app/models/fluentd/setting/config.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/fluentd/setting/config.rb b/app/models/fluentd/setting/config.rb index 6cc0b2c..ed5ba74 100644 --- a/app/models/fluentd/setting/config.rb +++ b/app/models/fluentd/setting/config.rb @@ -3,26 +3,26 @@ require 'fluent/config' class Fluentd module Setting class Config - attr_reader :config, :file + attr_reader :fl_config, :file + delegate :elements, :to_s, to: :fl_config def initialize(config_file) - config = Fluent::Config.parse(IO.read(config_file), config_file, nil, true) - @config = config + @fl_config = Fluent::Config.parse(IO.read(config_file), config_file, nil, true) @file = config_file end def empty? - config.elements.length.zero? + elements.length.zero? end def sources - config.elements.find_all do |elm| + elements.find_all do |elm| elm.name == "source" end end def matches - config.elements.find_all do |elm| + elements.find_all do |elm| elm.name == "match" end end From 86351718f34c92d673d79104aef54c85fc0c0e84 Mon Sep 17 00:00:00 2001 From: uu59 Date: Tue, 25 Nov 2014 17:51:57 +0900 Subject: [PATCH 02/11] Add JSON API for changing config by section --- app/controllers/api/settings_controller.rb | 45 +++++++++++++++++++ app/models/fluentd/setting/config.rb | 10 ++++- app/views/api/settings/_element.json.jbuilder | 6 +++ app/views/api/settings/index.json.jbuilder | 3 ++ app/views/api/settings/show.json.jbuilder | 1 + config/application.rb | 1 + config/routes.rb | 2 + 7 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 app/controllers/api/settings_controller.rb create mode 100644 app/views/api/settings/_element.json.jbuilder create mode 100644 app/views/api/settings/index.json.jbuilder create mode 100644 app/views/api/settings/show.json.jbuilder diff --git a/app/controllers/api/settings_controller.rb b/app/controllers/api/settings_controller.rb new file mode 100644 index 0000000..8a6f68c --- /dev/null +++ b/app/controllers/api/settings_controller.rb @@ -0,0 +1,45 @@ +class Api::SettingsController < ApplicationController + before_action :login_required + before_action :find_fluentd + before_action :set_config + before_action :set_section, only: [:show, :update, :destroy] + helper_method :element_id + respond_to :json + + def index + end + + def update + coming = Fluent::Config::V1Parser.parse(params[:body], @fluentd.config_file) + current = @section + index = @config.elements.index current + @config.elements[index] = coming.elements.first + @config.write_to_file + head :no_content # 204 + end + + def destroy + @config.elements.delete @section + @config.write_to_file + head :no_content # 204 + end + + private + + def set_config + # TODO: not found + @config = Fluentd::Setting::Config.new(@fluentd.config_file) + end + + def set_section + # TODO: not found + @section = @config.elements.find do |elm| + element_id(elm) == params[:id] + end + end + + def element_id(element) + index = @config.elements.index(element) # TODO: not found + "#{"%06d" % index}#{Digest::MD5.hexdigest(element.to_s)}" + end +end diff --git a/app/models/fluentd/setting/config.rb b/app/models/fluentd/setting/config.rb index ed5ba74..45d0fed 100644 --- a/app/models/fluentd/setting/config.rb +++ b/app/models/fluentd/setting/config.rb @@ -4,7 +4,7 @@ class Fluentd module Setting class Config attr_reader :fl_config, :file - delegate :elements, :to_s, to: :fl_config + delegate :elements, to: :fl_config def initialize(config_file) @fl_config = Fluent::Config.parse(IO.read(config_file), config_file, nil, true) @@ -26,6 +26,14 @@ class Fluentd elm.name == "match" end end + + def write_to_file + File.open(file, "w"){|f| f.write formatted } + end + + def formatted + fl_config.to_s.gsub(/<\/?ROOT>/, "").strip_heredoc.gsub(%r|^$|, "\\0\n") + end end end end diff --git a/app/views/api/settings/_element.json.jbuilder b/app/views/api/settings/_element.json.jbuilder new file mode 100644 index 0000000..bc58a7d --- /dev/null +++ b/app/views/api/settings/_element.json.jbuilder @@ -0,0 +1,6 @@ +json.id element_id(element) +json.name element.name +json.type element["type"] +json.arg element.arg +json.settings element +json.content element.to_s diff --git a/app/views/api/settings/index.json.jbuilder b/app/views/api/settings/index.json.jbuilder new file mode 100644 index 0000000..2b565f8 --- /dev/null +++ b/app/views/api/settings/index.json.jbuilder @@ -0,0 +1,3 @@ +json.array! @config.elements do |elm| + json.partial! "api/settings/element", element: elm +end diff --git a/app/views/api/settings/show.json.jbuilder b/app/views/api/settings/show.json.jbuilder new file mode 100644 index 0000000..a4e3486 --- /dev/null +++ b/app/views/api/settings/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "api/settings/element", element: @section diff --git a/config/application.rb b/config/application.rb index 1d09d9e..dfbc258 100644 --- a/config/application.rb +++ b/config/application.rb @@ -19,6 +19,7 @@ require "jquery-rails" require "sucker_punch" require "settingslogic" require "kramdown-haml" +require "jbuilder" module FluentdUi class Application < Rails::Application diff --git a/config/routes.rb b/config/routes.rb index 6bfc44d..c698a5d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -93,5 +93,7 @@ Rails.application.routes.draw do get "file_preview" post "regexp_preview" post "grok_to_regexp" + + resources :settings, only: [:index, :show, :update, :destroy], defaults: { format: "json" } end end From 763c3a4a95b4c1f559199d6a59cbf1ad1b04a760 Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 13:43:24 +0900 Subject: [PATCH 03/11] Vue-ify setting display --- app/assets/javascripts/vue/settings.js | 44 +++++++++++++++++++ .../fluentd/settings_controller.rb | 3 +- .../settings/source_and_output.html.haml | 29 +++--------- app/views/shared/vue/_setting.html.erb | 14 ++++++ 4 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 app/assets/javascripts/vue/settings.js create mode 100644 app/views/shared/vue/_setting.html.erb diff --git a/app/assets/javascripts/vue/settings.js b/app/assets/javascripts/vue/settings.js new file mode 100644 index 0000000..d212c5b --- /dev/null +++ b/app/assets/javascripts/vue/settings.js @@ -0,0 +1,44 @@ +;(function(){ + "use strict"; + + $(function(){ + var el = document.querySelector("#vue-setting"); + if(!el) return; + + new Vue({ + el: el, + data: { + sections: { + sources: [], + matches: [] + } + }, + created: function() { + this.update(); + }, + components: { + section: { + template: "#vue-setting-section" + } + }, + methods: { + update: function() { + var self = this; + $.getJSON("/api/settings", function(data){ + var sources = []; + var matches = []; + data.forEach(function(v){ + if(v.name === "source"){ + sources.push(v); + }else{ + matches.push(v); + } + }); + self.sections.sources = sources; + self.sections.matches = matches; + }); + } + } + }); + }); +})(); diff --git a/app/controllers/fluentd/settings_controller.rb b/app/controllers/fluentd/settings_controller.rb index 4d5ad67..54fcef9 100644 --- a/app/controllers/fluentd/settings_controller.rb +++ b/app/controllers/fluentd/settings_controller.rb @@ -17,6 +17,7 @@ class Fluentd::SettingsController < ApplicationController end def source_and_output - @config = Fluentd::Setting::Config.new(@fluentd.config_file) + # TODO: error handling if config file has invalid syntax + # @config = Fluentd::Setting::Config.new(@fluentd.config_file) end end diff --git a/app/views/fluentd/settings/source_and_output.html.haml b/app/views/fluentd/settings/source_and_output.html.haml index 84f673f..c652585 100644 --- a/app/views/fluentd/settings/source_and_output.html.haml +++ b/app/views/fluentd/settings/source_and_output.html.haml @@ -46,33 +46,18 @@ = icon('fa-file-text-o fa-lg') = t("fluentd.common.setup_out_forward") -.current-settings += render "shared/vue/setting" + +#vue-setting.current-settings %h2= t('.current') .row .col-xs-6.input %h3= t('.in') - - if @config.sources.empty? + %div{"v-if" => "sections.sources.length == 0"} %p.empty= t('.setting_empty') - - else - - @config.sources.each_with_index do |elm, idx| - .panel.panel-default - .panel-heading{"data-toggle" => "collapse", "href" => "#source#{idx}", "title" => elm.inspect} - = elm["type"] - = icon('fa-caret-down') - .panel-body.collapse{"id" => "source#{idx}"} - %pre= elm.to_s + %div{"v-repeat" => "sections.sources", "v-component" => "section"} .col-xs-6.output %h3= t('.out') - - if @config.matches.empty? + %div{"v-if" => "sections.matches.length == 0"} %p.empty= t('.setting_empty') - - else - - @config.matches.each_with_index do |elm, idx| - .panel.panel-default - .panel-heading{"data-toggle" => "collapse", "href" => "#match#{idx}", "title" => elm.inspect} - = elm["type"] - ( - = elm.arg - ) - = icon('fa-caret-down') - .panel-body.collapse{"id" => "match#{idx}"} - %pre= elm.to_s + %div{"v-repeat" => "sections.matches", "v-component" => "section"} diff --git a/app/views/shared/vue/_setting.html.erb b/app/views/shared/vue/_setting.html.erb new file mode 100644 index 0000000..61726ef --- /dev/null +++ b/app/views/shared/vue/_setting.html.erb @@ -0,0 +1,14 @@ + From cad387516e3d144472c4972119191d53c7e90e37 Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 14:03:34 +0900 Subject: [PATCH 04/11] Hide components until initial JSON loading finished --- app/assets/javascripts/vue/settings.js | 2 ++ app/views/fluentd/settings/source_and_output.html.haml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/vue/settings.js b/app/assets/javascripts/vue/settings.js index d212c5b..4aed4bf 100644 --- a/app/assets/javascripts/vue/settings.js +++ b/app/assets/javascripts/vue/settings.js @@ -8,6 +8,7 @@ new Vue({ el: el, data: { + loaded: false, sections: { sources: [], matches: [] @@ -36,6 +37,7 @@ }); self.sections.sources = sources; self.sections.matches = matches; + self.loaded = true; }); } } diff --git a/app/views/fluentd/settings/source_and_output.html.haml b/app/views/fluentd/settings/source_and_output.html.haml index c652585..521603f 100644 --- a/app/views/fluentd/settings/source_and_output.html.haml +++ b/app/views/fluentd/settings/source_and_output.html.haml @@ -53,11 +53,11 @@ .row .col-xs-6.input %h3= t('.in') - %div{"v-if" => "sections.sources.length == 0"} + %div{"v-if" => "loaded && sections.sources.length == 0"} %p.empty= t('.setting_empty') %div{"v-repeat" => "sections.sources", "v-component" => "section"} .col-xs-6.output %h3= t('.out') - %div{"v-if" => "sections.matches.length == 0"} + %div{"v-if" => "loaded && sections.matches.length == 0"} %p.empty= t('.setting_empty') %div{"v-repeat" => "sections.matches", "v-component" => "section"} From 00c2eb1e5a70d6edc8390d59cf0b7253c1dfe553 Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 15:09:53 +0900 Subject: [PATCH 05/11] CRUD for each setting section --- app/assets/javascripts/vue/settings.js | 63 +++++++++++++++++++++- app/assets/stylesheets/common.css.scss | 6 +++ app/controllers/api/settings_controller.rb | 4 +- app/views/shared/vue/_setting.html.erb | 11 +++- config/locales/translation_en.yml | 1 + config/locales/translation_ja.yml | 1 + 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/vue/settings.js b/app/assets/javascripts/vue/settings.js index 4aed4bf..184d3d0 100644 --- a/app/assets/javascripts/vue/settings.js +++ b/app/assets/javascripts/vue/settings.js @@ -19,7 +19,68 @@ }, components: { section: { - template: "#vue-setting-section" + template: "#vue-setting-section", + data: { + mode: "default", + processing: false, + editContent: null + }, + created: function(){ + this.initialState(); + }, + computed: { + endpoint: function(){ + return "/api/settings/" + this.id; + } + }, + methods: { + onCancel: function(ev) { + this.initialState(); + }, + onEdit: function(ev) { + this.mode = "edit"; + }, + onDelete: function(ev) { + if(!confirm("really?")) return; + this.destroy(); + }, + onSubmit: function(ev) { + this.processing = true; + var self = this; + $.ajax({ + url: this.endpoint, + method: "POST", + data: { + _method: "PATCH", + id: this.id, + content: this.editContent + } + }).then(function(data){ + // NOTE: child VM update doesn't effect to parent VM (at least Vue v0.10) + self.$data = data; + self.initialState(); + }).always(function(){ + self.processing = false; + }); + }, + initialState: function(){ + this.mode = "default"; + this.editContent = this.content; + }, + destroy: function(){ + var self = this; + $.ajax({ + url: this.endpoint, + method: "POST", + data: { + _method: "DELETE", + id: this.id + } + }).then(function(){ + self.$destroy(); + }); + } + } } }, methods: { diff --git a/app/assets/stylesheets/common.css.scss b/app/assets/stylesheets/common.css.scss index b60b47f..1cbe18f 100644 --- a/app/assets/stylesheets/common.css.scss +++ b/app/assets/stylesheets/common.css.scss @@ -150,3 +150,9 @@ label { .nav > li > a.section { color: #777; } + + +#vue-setting textarea { + min-height: 12em; + resize: both; +} diff --git a/app/controllers/api/settings_controller.rb b/app/controllers/api/settings_controller.rb index 8a6f68c..467e09a 100644 --- a/app/controllers/api/settings_controller.rb +++ b/app/controllers/api/settings_controller.rb @@ -10,12 +10,12 @@ class Api::SettingsController < ApplicationController end def update - coming = Fluent::Config::V1Parser.parse(params[:body], @fluentd.config_file) + coming = Fluent::Config::V1Parser.parse(params[:content], @fluentd.config_file) current = @section index = @config.elements.index current @config.elements[index] = coming.elements.first @config.write_to_file - head :no_content # 204 + redirect_to api_setting_path(id: element_id(coming.elements.first)) end def destroy diff --git a/app/views/shared/vue/_setting.html.erb b/app/views/shared/vue/_setting.html.erb index 61726ef..ed23cce 100644 --- a/app/views/shared/vue/_setting.html.erb +++ b/app/views/shared/vue/_setting.html.erb @@ -7,7 +7,16 @@
-
{{ content }}
+
{{ content }}
+

+ +

+

+ + + + +

diff --git a/config/locales/translation_en.yml b/config/locales/translation_en.yml index 643a84f..1af576b 100644 --- a/config/locales/translation_en.yml +++ b/config/locales/translation_en.yml @@ -31,6 +31,7 @@ en: no_alert: Nothing update_password: Update Password detail: Detail + cancel: Cancel create: Create update: Update & Restart edit: Edit diff --git a/config/locales/translation_ja.yml b/config/locales/translation_ja.yml index 873f90a..51dcf07 100644 --- a/config/locales/translation_ja.yml +++ b/config/locales/translation_ja.yml @@ -31,6 +31,7 @@ ja: no_alert: 通知なし update_password: パスワード更新 detail: 詳細 + cancel: キャンセル create: 作成 update: 更新 edit: 編集 From eb465221b86bcd525578a95e36c748b989dddab1 Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 15:44:11 +0900 Subject: [PATCH 06/11] Error handling --- app/controllers/api/settings_controller.rb | 16 +++++++++++++--- app/controllers/fluentd/settings_controller.rb | 14 ++++++++++++-- app/views/fluentd/settings/edit.html.haml | 3 +++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/settings_controller.rb b/app/controllers/api/settings_controller.rb index 467e09a..a781a02 100644 --- a/app/controllers/api/settings_controller.rb +++ b/app/controllers/api/settings_controller.rb @@ -13,12 +13,20 @@ class Api::SettingsController < ApplicationController coming = Fluent::Config::V1Parser.parse(params[:content], @fluentd.config_file) current = @section index = @config.elements.index current + unless index + render_404 + return + end @config.elements[index] = coming.elements.first @config.write_to_file redirect_to api_setting_path(id: element_id(coming.elements.first)) end def destroy + unless @config.elements.index(@section) + render_404 + return + end @config.elements.delete @section @config.write_to_file head :no_content # 204 @@ -27,19 +35,21 @@ class Api::SettingsController < ApplicationController private def set_config - # TODO: not found @config = Fluentd::Setting::Config.new(@fluentd.config_file) end def set_section - # TODO: not found @section = @config.elements.find do |elm| element_id(elm) == params[:id] end end def element_id(element) - index = @config.elements.index(element) # TODO: not found + index = @config.elements.index(element) "#{"%06d" % index}#{Digest::MD5.hexdigest(element.to_s)}" end + + def render_404 + render nothing: true, status: 404 + end end diff --git a/app/controllers/fluentd/settings_controller.rb b/app/controllers/fluentd/settings_controller.rb index 54fcef9..641f810 100644 --- a/app/controllers/fluentd/settings_controller.rb +++ b/app/controllers/fluentd/settings_controller.rb @@ -1,23 +1,33 @@ class Fluentd::SettingsController < ApplicationController before_action :login_required before_action :find_fluentd + before_action :set_config, only: [:show, :edit, :update] def show - @config = @fluentd.agent.config end def edit - @config = @fluentd.agent.config end def update + Fluent::Config::V1Parser.parse(params[:config], @fluentd.config_file) @fluentd.agent.config_write params[:config] @fluentd.agent.restart if @fluentd.agent.running? redirect_to daemon_setting_path(@fluentd) + rescue Fluent::ConfigParseError => e + @config = params[:config] + @error = e.message + render "edit" end def source_and_output # TODO: error handling if config file has invalid syntax # @config = Fluentd::Setting::Config.new(@fluentd.config_file) end + + private + + def set_config + @config = @fluentd.agent.config + end end diff --git a/app/views/fluentd/settings/edit.html.haml b/app/views/fluentd/settings/edit.html.haml index 382ee5a..43ac76a 100644 --- a/app/views/fluentd/settings/edit.html.haml +++ b/app/views/fluentd/settings/edit.html.haml @@ -1,5 +1,8 @@ - page_title t('.page_title', label: @fluentd.label) +- if @error + %pre.alert.alert-danger= @error + = form_tag(daemon_setting_path(@fluentd), method: :patch) do .form-group = text_area_tag "config", @config, class: "form-control", rows: 40 From 244f28caaea393ca551e3fb5a5731cb8fcd99b3b Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 16:13:20 +0900 Subject: [PATCH 07/11] Add test --- .../fluentd/setting/source_and_output_spec.rb | 56 +++++++++++++++++++ spec/spec_helper.rb | 12 ++++ 2 files changed, 68 insertions(+) diff --git a/spec/features/fluentd/setting/source_and_output_spec.rb b/spec/features/fluentd/setting/source_and_output_spec.rb index aba8121..9f45ce1 100644 --- a/spec/features/fluentd/setting/source_and_output_spec.rb +++ b/spec/features/fluentd/setting/source_and_output_spec.rb @@ -89,4 +89,60 @@ describe "source_and_output", js: true do end end end + + describe "edit, update, delete" do + let(:config_contents) { <<-CONF.strip_heredoc } + + type forward + port 24224 + + CONF + let(:new_config) { <<-CONF.strip_heredoc } + + type http + port 8899 + + CONF + + before do + all(".input .panel .panel-heading").first.click + end + + it "click edit button transform textarea, then click cancel button to be reset" do + page.should_not have_css('.input textarea') + find(".btn", text: I18n.t('terms.edit')).click + page.should have_css('.input textarea') + find('.input textarea').value.should == config_contents + find('.input textarea').set "foo" + find(".btn", text: I18n.t('terms.cancel')).click + content = wait_until do + page.evaluate_script("document.querySelector('.input pre').textContent") + end + content.should == config_contents + daemon.agent.config.strip.should == config_contents.strip + end + + it "click edit button transform textarea, then click update button to be stored" do + page.should_not have_css('.input textarea') + find(".btn", text: I18n.t('terms.edit')).click + page.should have_css('.input textarea') + find('.input textarea').value.should == config_contents + find('.input textarea').set new_config + find(".btn", text: I18n.t('terms.update')).click + content = wait_until do + page.evaluate_script("document.querySelector('.input pre').textContent") + end + content.should == new_config + daemon.agent.config.strip.should == new_config.strip + end + + it "click delete button transform textarea" do + page.should have_css('.input .panel-body') + page.execute_script "__backup = window.confirm; window.confirm = function(){return true;}" + find(".btn", text: I18n.t('terms.destroy')).click + page.should_not have_css('.input .panel-body') + page.execute_script "window.confirm = __backup;" + daemon.agent.config.strip.should == "" + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 603e70f..21554b3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -34,6 +34,18 @@ RSpec.configure do |config| # Syntax sugar to use the FactoryGirl methods directly instead FactoryGirl.create ete. config.include FactoryGirl::Syntax::Methods config.include LoginMacro + def wait_until(seconds = 5, &block) + timeout(seconds) do + loop do + begin + ret = block.call + break ret if ret + rescue Capybara::Poltergeist::JavascriptError + end + sleep 0.01 + end + end + end # If true, the base class of anonymous controllers will be inferred # automatically. This will be the default behavior in future versions of From 40c95eaca772221fb8b92b5605be8efacf013847 Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 16:25:44 +0900 Subject: [PATCH 08/11] Refactor spec helpers --- .../fluentd/setting/source_and_output_spec.rb | 6 +++--- spec/spec_helper.rb | 13 +----------- spec/support/javascript_macro.rb | 21 +++++++++++++++++++ 3 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 spec/support/javascript_macro.rb diff --git a/spec/features/fluentd/setting/source_and_output_spec.rb b/spec/features/fluentd/setting/source_and_output_spec.rb index 9f45ce1..2229e56 100644 --- a/spec/features/fluentd/setting/source_and_output_spec.rb +++ b/spec/features/fluentd/setting/source_and_output_spec.rb @@ -138,10 +138,10 @@ describe "source_and_output", js: true do it "click delete button transform textarea" do page.should have_css('.input .panel-body') - page.execute_script "__backup = window.confirm; window.confirm = function(){return true;}" - find(".btn", text: I18n.t('terms.destroy')).click + confirm_dialog(true) do + find(".btn", text: I18n.t('terms.destroy')).click + end page.should_not have_css('.input .panel-body') - page.execute_script "window.confirm = __backup;" daemon.agent.config.strip.should == "" end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 21554b3..532be0d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -34,18 +34,7 @@ RSpec.configure do |config| # Syntax sugar to use the FactoryGirl methods directly instead FactoryGirl.create ete. config.include FactoryGirl::Syntax::Methods config.include LoginMacro - def wait_until(seconds = 5, &block) - timeout(seconds) do - loop do - begin - ret = block.call - break ret if ret - rescue Capybara::Poltergeist::JavascriptError - end - sleep 0.01 - end - end - end + config.include JavascriptMacro # If true, the base class of anonymous controllers will be inferred # automatically. This will be the default behavior in future versions of diff --git a/spec/support/javascript_macro.rb b/spec/support/javascript_macro.rb new file mode 100644 index 0000000..991ab86 --- /dev/null +++ b/spec/support/javascript_macro.rb @@ -0,0 +1,21 @@ +module JavascriptMacro + def wait_until(seconds = 5, &block) + timeout(seconds) do + loop do + begin + ret = block.call + break ret if ret + rescue Capybara::Poltergeist::JavascriptError + end + sleep 0.01 + end + end + end + + def confirm_dialog(ret, &block) + page.execute_script "__backup = window.confirm; window.confirm = function(){return #{ret};}" + block.call + ensure + page.execute_script "window.confirm = __backup;" + end +end From 6b3add215c614b13f18f59b71c723b6643a5dc20 Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 16:27:33 +0900 Subject: [PATCH 09/11] Add spec for delete button clicked then cancel clicked --- spec/features/fluentd/setting/source_and_output_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/features/fluentd/setting/source_and_output_spec.rb b/spec/features/fluentd/setting/source_and_output_spec.rb index 2229e56..5cb7d95 100644 --- a/spec/features/fluentd/setting/source_and_output_spec.rb +++ b/spec/features/fluentd/setting/source_and_output_spec.rb @@ -144,5 +144,14 @@ describe "source_and_output", js: true do page.should_not have_css('.input .panel-body') daemon.agent.config.strip.should == "" end + + it "click delete button then cancel it" do + page.should have_css('.input .panel-body') + confirm_dialog(false) do + find(".btn", text: I18n.t('terms.destroy')).click + end + page.should have_css('.input .panel-body') + daemon.agent.config.strip.should == config_contents.strip + end end end From dce4a046eb42ecdc18e5717c8163b3e4f3ad2095 Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 16:58:13 +0900 Subject: [PATCH 10/11] Reload after delete section to fix id mismatched --- app/assets/javascripts/vue/settings.js | 7 ++++++- app/views/fluentd/settings/source_and_output.html.haml | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/vue/settings.js b/app/assets/javascripts/vue/settings.js index 184d3d0..6148e88 100644 --- a/app/assets/javascripts/vue/settings.js +++ b/app/assets/javascripts/vue/settings.js @@ -9,6 +9,7 @@ el: el, data: { loaded: false, + loading: false, sections: { sources: [], matches: [] @@ -77,7 +78,7 @@ id: this.id } }).then(function(){ - self.$destroy(); + self.$parent.update(); }); } } @@ -85,6 +86,7 @@ }, methods: { update: function() { + this.loading = true; var self = this; $.getJSON("/api/settings", function(data){ var sources = []; @@ -99,6 +101,9 @@ self.sections.sources = sources; self.sections.matches = matches; self.loaded = true; + setTimeout(function(){ + self.loading = false; + }, 500); }); } } diff --git a/app/views/fluentd/settings/source_and_output.html.haml b/app/views/fluentd/settings/source_and_output.html.haml index 521603f..28dba99 100644 --- a/app/views/fluentd/settings/source_and_output.html.haml +++ b/app/views/fluentd/settings/source_and_output.html.haml @@ -49,7 +49,10 @@ = render "shared/vue/setting" #vue-setting.current-settings - %h2= t('.current') + %h2 + = t('.current') + %span{"v-on" => "click: update", "v-if" => "!loading"}= icon('fa-refresh') + %span{"v-if" => "loading"}= icon('fa-spin fa-refresh') .row .col-xs-6.input %h3= t('.in') From b94cc5eadbd8037f271cf8223c2f72e8e43c599f Mon Sep 17 00:00:00 2001 From: uu59 Date: Wed, 26 Nov 2014 16:58:26 +0900 Subject: [PATCH 11/11] Fix text: terms.update -> terms.save --- app/views/shared/vue/_setting.html.erb | 2 +- config/locales/translation_en.yml | 1 + config/locales/translation_ja.yml | 1 + spec/features/fluentd/setting/source_and_output_spec.rb | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/shared/vue/_setting.html.erb b/app/views/shared/vue/_setting.html.erb index ed23cce..513c27e 100644 --- a/app/views/shared/vue/_setting.html.erb +++ b/app/views/shared/vue/_setting.html.erb @@ -15,7 +15,7 @@ - +

diff --git a/config/locales/translation_en.yml b/config/locales/translation_en.yml index 1af576b..9fad53e 100644 --- a/config/locales/translation_en.yml +++ b/config/locales/translation_en.yml @@ -34,6 +34,7 @@ en: cancel: Cancel create: Create update: Update & Restart + save: Save edit: Edit destroy: Destroy new: New diff --git a/config/locales/translation_ja.yml b/config/locales/translation_ja.yml index 51dcf07..0e77d10 100644 --- a/config/locales/translation_ja.yml +++ b/config/locales/translation_ja.yml @@ -34,6 +34,7 @@ ja: cancel: キャンセル create: 作成 update: 更新 + save: 保存 edit: 編集 destroy: 削除 new: 新規作成 diff --git a/spec/features/fluentd/setting/source_and_output_spec.rb b/spec/features/fluentd/setting/source_and_output_spec.rb index 5cb7d95..089cded 100644 --- a/spec/features/fluentd/setting/source_and_output_spec.rb +++ b/spec/features/fluentd/setting/source_and_output_spec.rb @@ -128,7 +128,7 @@ describe "source_and_output", js: true do page.should have_css('.input textarea') find('.input textarea').value.should == config_contents find('.input textarea').set new_config - find(".btn", text: I18n.t('terms.update')).click + find(".btn", text: I18n.t('terms.save')).click content = wait_until do page.evaluate_script("document.querySelector('.input pre').textContent") end