From f1ecf53c1e55fbbc66cb2d7d12fb411cbfc2ace8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 12 Nov 2013 13:47:28 +0200 Subject: [PATCH 1/7] Broadcast message model + migrations Signed-off-by: Dmitriy Zaporozhets --- app/models/broadcast_message.rb | 5 +++++ .../20131112114325_create_broadcast_messages.rb | 12 ++++++++++++ db/schema.rb | 11 ++++++++++- spec/factories/broadcast_messages.rb | 10 ++++++++++ spec/models/broadcast_message_spec.rb | 7 +++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 app/models/broadcast_message.rb create mode 100644 db/migrate/20131112114325_create_broadcast_messages.rb create mode 100644 spec/factories/broadcast_messages.rb create mode 100644 spec/models/broadcast_message_spec.rb diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb new file mode 100644 index 0000000000..0318c9b678 --- /dev/null +++ b/app/models/broadcast_message.rb @@ -0,0 +1,5 @@ +class BroadcastMessage < ActiveRecord::Base + attr_accessible :alert_type, :ends_at, :message, :starts_at + + validates :message, presence: true +end diff --git a/db/migrate/20131112114325_create_broadcast_messages.rb b/db/migrate/20131112114325_create_broadcast_messages.rb new file mode 100644 index 0000000000..147178e9dc --- /dev/null +++ b/db/migrate/20131112114325_create_broadcast_messages.rb @@ -0,0 +1,12 @@ +class CreateBroadcastMessages < ActiveRecord::Migration + def change + create_table :broadcast_messages do |t| + t.text :message, null: false + t.datetime :starts_at + t.datetime :ends_at + t.integer :alert_type + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 88c6a545d9..a03e471318 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,16 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20131106151520) do +ActiveRecord::Schema.define(:version => 20131112114325) do + + create_table "broadcast_messages", :force => true do |t| + t.text "message", :null => false + t.datetime "starts_at" + t.datetime "ends_at" + t.integer "alert_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end create_table "deploy_keys_projects", :force => true do |t| t.integer "deploy_key_id", :null => false diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb new file mode 100644 index 0000000000..6b649af832 --- /dev/null +++ b/spec/factories/broadcast_messages.rb @@ -0,0 +1,10 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :broadcast_message do + message "MyText" + starts_at "2013-11-12 13:43:25" + ends_at "2013-11-12 13:43:25" + alert_type 1 + end +end diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb new file mode 100644 index 0000000000..09f79f4d62 --- /dev/null +++ b/spec/models/broadcast_message_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe BroadcastMessage do + subject { create(:broadcast_message) } + + it { should be_valid } +end From dd501aa7a79644919ba0c47d1ed764b6db768c8d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 12 Nov 2013 14:28:12 +0200 Subject: [PATCH 2/7] Broadcast messages scaffold in admin area Signed-off-by: Dmitriy Zaporozhets --- .../stylesheets/gitlab_bootstrap/forms.scss | 6 +++ .../admin/broadcast_messages_controller.rb | 23 +++++++++++ app/models/broadcast_message.rb | 2 + .../admin/broadcast_messages/index.html.haml | 41 +++++++++++++++++++ config/routes.rb | 1 + 5 files changed, 73 insertions(+) create mode 100644 app/controllers/admin/broadcast_messages_controller.rb create mode 100644 app/views/admin/broadcast_messages/index.html.haml diff --git a/app/assets/stylesheets/gitlab_bootstrap/forms.scss b/app/assets/stylesheets/gitlab_bootstrap/forms.scss index a2612166c7..3df5ebab27 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/forms.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/forms.scss @@ -49,3 +49,9 @@ fieldset legend { font-size: 16px; margin-bottom: 10px; } + +.datetime-controls { + select { + width: 100px; + } +} diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb new file mode 100644 index 0000000000..3ba8d09bc8 --- /dev/null +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -0,0 +1,23 @@ +class Admin::BroadcastMessagesController < Admin::ApplicationController + before_filter :broadcast_messages + + def index + @broadcast_message = BroadcastMessage.new + end + + def create + @broadcast_message = BroadcastMessage.new(params[:broadcast_message]) + + if @broadcast_message.save + redirect_to admin_broadcast_messages_path, notice: 'Broadcast Message was successfully created.' + else + render :index + end + end + + protected + + def broadcast_messages + @broadcast_messages ||= BroadcastMessage.order("starts_at DESC").page(params[:page]) + end +end diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb index 0318c9b678..69636de90e 100644 --- a/app/models/broadcast_message.rb +++ b/app/models/broadcast_message.rb @@ -2,4 +2,6 @@ class BroadcastMessage < ActiveRecord::Base attr_accessible :alert_type, :ends_at, :message, :starts_at validates :message, presence: true + validates :starts_at, presence: true + validates :ends_at, presence: true end diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml new file mode 100644 index 0000000000..22f7b71912 --- /dev/null +++ b/app/views/admin/broadcast_messages/index.html.haml @@ -0,0 +1,41 @@ +%h3.page-title + Broadcast Messages +%p.light + Broadcast messages displayed for every user and can be used to notify application about scheduled maintenance. +%hr + += form_for [:admin, @broadcast_message] do |f| + -if @broadcast_message.errors.any? + .alert.alert-error + - @broadcast_message.errors.full_messages.each do |msg| + %p= msg + .control-group + = f.label :message + .controls + = f.text_area :message, class: "input-xxlarge", rows: 2, required: true + .control-group + = f.label :starts_at + .controls.datetime-controls + = f.datetime_select :starts_at + .control-group + = f.label :ends_at + .controls.datetime-controls + = f.datetime_select :ends_at + .form-actions + = f.submit "Add broadcast message", class: "btn btn-create" + +-if @broadcast_messages.any? + %ul.bordered-list + - @broadcast_messages.each do |broadcast_message| + %li + .pull-right + - if broadcast_message.starts_at + %strong + #{broadcast_message.starts_at.to_s(:short)} + \... + - if broadcast_message.ends_at + %strong + #{broadcast_message.ends_at.to_s(:short)} + .message= broadcast_message.message + + = paginate @broadcast_messages diff --git a/config/routes.rb b/config/routes.rb index 58bbd2b650..d41a07872e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -86,6 +86,7 @@ Gitlab::Application.routes.draw do get :test end + resources :broadcast_messages, only: [:index, :create] resource :logs, only: [:show] resource :background_jobs, controller: 'background_jobs', only: [:show] resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, only: [:index, :show] From 90d599397fdfbf35ccdf3593afe391f984fba601 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 12 Nov 2013 14:29:43 +0200 Subject: [PATCH 3/7] Add broadcast messages to admin nav Signed-off-by: Dmitriy Zaporozhets --- app/views/layouts/nav/_admin.html.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index 73946f9988..48c569f868 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -10,6 +10,8 @@ = link_to "Users", admin_users_path = nav_link(controller: :logs) do = link_to "Logs", admin_logs_path + = nav_link(controller: :broadcast_messages) do + = link_to "Messages", admin_broadcast_messages_path = nav_link(controller: :hooks) do = link_to "Hooks", admin_hooks_path = nav_link(controller: :background_jobs) do From 963a31144b0d69af7b08e1912965a920636ce600 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 12 Nov 2013 14:32:17 +0200 Subject: [PATCH 4/7] Active tab tests for admin broadcast messages Signed-off-by: Dmitriy Zaporozhets --- features/admin/active_tab.feature | 5 +++++ features/steps/admin/admin_active_tab.rb | 4 ++++ features/steps/shared/paths.rb | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/features/admin/active_tab.feature b/features/admin/active_tab.feature index 226d3d5d5b..15fcda45e4 100644 --- a/features/admin/active_tab.feature +++ b/features/admin/active_tab.feature @@ -27,6 +27,11 @@ Feature: Admin active tab Then the active main tab should be Logs And no other main tabs should be active + Scenario: On Admin Messages + Given I visit admin messages page + Then the active main tab should be Messages + And no other main tabs should be active + Scenario: On Admin Hooks Given I visit admin hooks page Then the active main tab should be Hooks diff --git a/features/steps/admin/admin_active_tab.rb b/features/steps/admin/admin_active_tab.rb index f14c5f396b..ccafe09c18 100644 --- a/features/steps/admin/admin_active_tab.rb +++ b/features/steps/admin/admin_active_tab.rb @@ -30,4 +30,8 @@ class AdminActiveTab < Spinach::FeatureSteps Then 'the active main tab should be Resque' do ensure_active_main_tab('Background Jobs') end + + Then 'the active main tab should be Messages' do + ensure_active_main_tab('Messages') + end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 156fa5bab4..987cd3120c 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -105,6 +105,10 @@ module SharedPaths visit admin_logs_path end + step 'I visit admin messages page' do + visit admin_broadcast_messages_path + end + step 'I visit admin hooks page' do visit admin_hooks_path end From c5b667351abcda4b5ac134873007a0ce47976e88 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 12 Nov 2013 15:08:20 +0200 Subject: [PATCH 5/7] Show broadcast message to users Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/common.scss | 7 +++++++ app/helpers/application_helper.rb | 4 ++++ app/models/broadcast_message.rb | 4 ++++ app/views/layouts/_broadcast.html.haml | 4 ++++ app/views/layouts/application.html.haml | 1 + app/views/layouts/projects.html.haml | 1 + spec/models/broadcast_message_spec.rb | 17 +++++++++++++++++ 7 files changed, 38 insertions(+) create mode 100644 app/views/layouts/_broadcast.html.haml diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 8cb8e1b327..56dbd9ac43 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -351,3 +351,10 @@ table { @extend .btn-new; padding: 5px 15px; } + +.broadcast-message { + padding: 10px; + text-align: center; + background: #555; + color: #BBB; +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e2d9790141..02cc696c72 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -208,4 +208,8 @@ module ApplicationHelper line += "..." if lines.size > 1 line end + + def broadcast_message + BroadcastMessage.current + end end diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb index 69636de90e..5b0040f6ca 100644 --- a/app/models/broadcast_message.rb +++ b/app/models/broadcast_message.rb @@ -4,4 +4,8 @@ class BroadcastMessage < ActiveRecord::Base validates :message, presence: true validates :starts_at, presence: true validates :ends_at, presence: true + + def self.current + where("ends_at > :now AND starts_at < :now", now: Time.zone.now).last + end end diff --git a/app/views/layouts/_broadcast.html.haml b/app/views/layouts/_broadcast.html.haml new file mode 100644 index 0000000000..4c4de743fd --- /dev/null +++ b/app/views/layouts/_broadcast.html.haml @@ -0,0 +1,4 @@ +- if broadcast_message.present? + .broadcast-message + %i.icon-bullhorn + = broadcast_message.message diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 792fe5e4a2..92edc71823 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -2,6 +2,7 @@ %html{ lang: "en"} = render "layouts/head", title: "Dashboard" %body{class: "#{app_theme} application", :'data-page' => body_data_page } + = render "layouts/broadcast" = render "layouts/head_panel", title: "Dashboard" = render "layouts/flash" %nav.main-nav diff --git a/app/views/layouts/projects.html.haml b/app/views/layouts/projects.html.haml index 6d8bf9b710..5ccb69769c 100644 --- a/app/views/layouts/projects.html.haml +++ b/app/views/layouts/projects.html.haml @@ -2,6 +2,7 @@ %html{ lang: "en"} = render "layouts/head", title: @project.name_with_namespace %body{class: "#{app_theme} project", :'data-page' => body_data_page, :'data-project-id' => @project.id } + = render "layouts/broadcast" = render "layouts/head_panel", title: project_title(@project) = render "layouts/init_auto_complete" = render "layouts/flash" diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb index 09f79f4d62..daaac73739 100644 --- a/spec/models/broadcast_message_spec.rb +++ b/spec/models/broadcast_message_spec.rb @@ -4,4 +4,21 @@ describe BroadcastMessage do subject { create(:broadcast_message) } it { should be_valid } + + describe :current do + it "should return last message if time match" do + broadcast_message = create(:broadcast_message, starts_at: Time.now.yesterday, ends_at: Time.now.tomorrow) + BroadcastMessage.current.should == broadcast_message + end + + it "should return nil if time not come" do + broadcast_message = create(:broadcast_message, starts_at: Time.now.tomorrow, ends_at: Time.now + 2.days) + BroadcastMessage.current.should be_nil + end + + it "should return nil if time has passed" do + broadcast_message = create(:broadcast_message, starts_at: Time.now - 2.days, ends_at: Time.now.yesterday) + BroadcastMessage.current.should be_nil + end + end end From 13a66040300241caf234726bfc72ca90ef4c34fd Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 12 Nov 2013 15:20:31 +0200 Subject: [PATCH 6/7] Ability to remvoe broadcast messages Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/sections/admin.scss | 6 ++++++ app/controllers/admin/broadcast_messages_controller.rb | 9 +++++++++ app/views/admin/broadcast_messages/index.html.haml | 7 ++++++- config/routes.rb | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/sections/admin.scss b/app/assets/stylesheets/sections/admin.scss index e189fd27ac..82556e91da 100644 --- a/app/assets/stylesheets/sections/admin.scss +++ b/app/assets/stylesheets/sections/admin.scss @@ -21,3 +21,9 @@ .controls { margin-left: 130px; } .form-actions { padding-left: 130px; background: #fff } } + +.broadcast-messages { + .message { + line-height: 2; + } +} diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index 3ba8d09bc8..9a70ef9d19 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -15,6 +15,15 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController end end + def destroy + BroadcastMessage.find(params[:id]).destroy + + respond_to do |format| + format.html { redirect_to :back } + format.js { render nothing: true } + end + end + protected def broadcast_messages diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml index 22f7b71912..fc750a4be7 100644 --- a/app/views/admin/broadcast_messages/index.html.haml +++ b/app/views/admin/broadcast_messages/index.html.haml @@ -25,7 +25,7 @@ = f.submit "Add broadcast message", class: "btn btn-create" -if @broadcast_messages.any? - %ul.bordered-list + %ul.bordered-list.broadcast-messages - @broadcast_messages.each do |broadcast_message| %li .pull-right @@ -36,6 +36,11 @@ - if broadcast_message.ends_at %strong #{broadcast_message.ends_at.to_s(:short)} +   + = link_to [:admin, broadcast_message], method: :delete, remote: true, class: 'remove-row btn btn-tiny' do + %i.icon-remove.cred + .message= broadcast_message.message + = paginate @broadcast_messages diff --git a/config/routes.rb b/config/routes.rb index d41a07872e..3b69239087 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -86,7 +86,7 @@ Gitlab::Application.routes.draw do get :test end - resources :broadcast_messages, only: [:index, :create] + resources :broadcast_messages, only: [:index, :create, :destroy] resource :logs, only: [:show] resource :background_jobs, controller: 'background_jobs', only: [:show] resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, only: [:index, :show] From 3397361fd7aeec711167c40b3fbab1e05a53b73d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 12 Nov 2013 18:56:48 +0200 Subject: [PATCH 7/7] Spinach test for broadcast messages Signed-off-by: Dmitriy Zaporozhets --- features/admin/broadcast_messages.feature | 13 +++++++++ .../steps/admin/admin_broadcast_messages.rb | 27 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 features/admin/broadcast_messages.feature create mode 100644 features/steps/admin/admin_broadcast_messages.rb diff --git a/features/admin/broadcast_messages.feature b/features/admin/broadcast_messages.feature new file mode 100644 index 0000000000..0294b51a7c --- /dev/null +++ b/features/admin/broadcast_messages.feature @@ -0,0 +1,13 @@ +Feature: Admin Broadcast Messages + Background: + Given I sign in as an admin + And application already has admin messages + And I visit admin messages page + + Scenario: See broadcast messages list + Then I should be all broadcast messages + + Scenario: Create a broadcast message + When submit form with new broadcast message + Then I should be redirected to admin messages page + And I should see newly created broadcast message diff --git a/features/steps/admin/admin_broadcast_messages.rb b/features/steps/admin/admin_broadcast_messages.rb new file mode 100644 index 0000000000..4dfaac06ae --- /dev/null +++ b/features/steps/admin/admin_broadcast_messages.rb @@ -0,0 +1,27 @@ +class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedAdmin + + step 'application already has admin messages' do + FactoryGirl.create(:broadcast_message, message: "Migration to new server") + end + + step 'I should be all broadcast messages' do + page.should have_content "Migration to new server" + end + + step 'submit form with new broadcast message' do + fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' + select '2018', from: "broadcast_message_ends_at_1i" + click_button "Add broadcast message" + end + + step 'I should be redirected to admin messages page' do + current_path.should == admin_broadcast_messages_path + end + + step 'I should see newly created broadcast message' do + page.should have_content 'Application update from 4:00 CST to 5:00 CST' + end +end