diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..5697e1a5492b8c6a10aca9496c1b266f2786f2f4 --- /dev/null +++ b/app/controllers/admin/services_controller.rb @@ -0,0 +1,51 @@ +class Admin::ServicesController < Admin::ApplicationController + before_filter :service, only: [:edit, :update] + + def index + @services = services_templates + end + + def edit + unless service.present? + redirect_to admin_application_settings_services_path, + alert: "Service is unknown or it doesn't exist" + end + end + + def update + if service.update_attributes(application_services_params[:service]) + redirect_to admin_application_settings_services_path, + notice: 'Application settings saved successfully' + else + render :edit + end + end + + private + + def services_templates + templates = [] + + allowed_templates.each do |service| + service_template = service.constantize + templates << service_template.where(template: true).first_or_create + end + + templates + end + + def allowed_templates + %w( JiraService RedmineService CustomIssueTrackerService ) + end + + def service + @service ||= Service.where(id: params[:id], template: true).first + end + + def application_services_params + params.permit(:id, + service: [ + :title, :project_url, :description, :issues_url, :new_issue_url + ]) + end +end diff --git a/app/models/project.rb b/app/models/project.rb index e53b268c8ea2652e675125b4b8fa42ce10ee7d59..f7cbbf3ace42bc63d113dadb27321e494f85633a 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -353,15 +353,30 @@ class Project < ActiveRecord::Base end def build_missing_services + services_templates = Service.where(template: true) + available_services_names.each do |service_name| - service = services.find { |service| service.to_param == service_name } + service = find_service(services, service_name) # If service is available but missing in db - # we should create an instance. Ex `create_gitlab_ci_service` - service = self.send :"create_#{service_name}_service" if service.nil? + if service.nil? + # We should check if template for the service exists + template = find_service(services_templates, service_name) + + if template.nil? + # If no template, we should create an instance. Ex `create_gitlab_ci_service` + service = self.send :"create_#{service_name}_service" + else + Service.create_from_template(self.id, template) + end + end end end + def find_service(list, name) + list.find { |service| service.to_param == name } + end + def available_services_names %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla asana emails_on_push gemnasium slack pushover buildbox bamboo teamcity jira redmine custom_issue_tracker) diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb index b19c02bab44a4266f7935abf529994e8a12b7cef..cb6426d180d5806699b3d25f57f6d0628040c304 100644 --- a/app/models/project_services/issue_tracker_service.rb +++ b/app/models/project_services/issue_tracker_service.rb @@ -77,12 +77,14 @@ class IssueTrackerService < Service end def set_project_url - id = self.project.issues_tracker_id + if self.project + id = self.project.issues_tracker_id - if id - issues_tracker['project_url'].gsub(":issues_tracker_id", id) - else - issues_tracker['project_url'] + if id + issues_tracker['project_url'].gsub(":issues_tracker_id", id) + end end + + issues_tracker['project_url'] end end diff --git a/app/models/service.rb b/app/models/service.rb index 4c4fe085c22df7c0c427901636bd5f0cdd3a840c..0099dbe65c0bc17e391302493dbf9f45ed5acb95 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -25,7 +25,7 @@ class Service < ActiveRecord::Base belongs_to :project has_one :service_hook - validates :project_id, presence: true + validates :project_id, presence: true, unless: Proc.new { |service| service.template? } scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') } @@ -33,6 +33,10 @@ class Service < ActiveRecord::Base active end + def template? + template + end + def category :common end @@ -94,7 +98,10 @@ class Service < ActiveRecord::Base self.category == :issue_tracker end - def self.issue_tracker_service_list - Service.select(&:issue_tracker?).map{ |s| s.to_param } + def self.create_from_template(project_id, template) + service = template.dup + service.template = false + service.project_id = project_id + service if service.save end end diff --git a/app/views/admin/application_settings/_external_issues_tracker_template.html.haml b/app/views/admin/application_settings/_external_issues_tracker_template.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..b998df446656c86894c3d1ffb9e91d7f6d14e66a --- /dev/null +++ b/app/views/admin/application_settings/_external_issues_tracker_template.html.haml @@ -0,0 +1,22 @@ +- service.fields.each do |field| + TOPD + / - name = field[:name] + / - value = "V"#@service.send(name) unless field[:type] == 'password' + / - type = field[:type] + / - placeholder = field[:placeholder] + / - choices = field[:choices] + / - default_choice = field[:default_choice] + + / .form-group + / = f.label name, class: "control-label" + / .col-sm-10 + / - if type == 'text' + / = f.text_field name, class: "form-control", placeholder: placeholder + / - elsif type == 'textarea' + / = f.text_area name, rows: 5, class: "form-control", placeholder: placeholder + / - elsif type == 'checkbox' + / = f.check_box name + / - elsif type == 'select' + / = f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" } + / - elsif type == 'password' + / = f.password_field name, class: 'form-control' diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..e869f45e2427c8f760067e74932990f0b3b45f4c --- /dev/null +++ b/app/views/admin/services/_form.html.haml @@ -0,0 +1,25 @@ +%h3.page-title + = @service.title + = boolean_to_icon @service.activated? + +%p #{@service.description} template + += form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'form-horizontal fieldset-form' } do |f| + - if @service.errors.any? + #error_explanation + .alert.alert-danger + - @service.errors.full_messages.each do |msg| + %p= msg + + - @service.fields.each do |field| + - name = field[:name] + - type = field[:type] + - placeholder = field[:placeholder] + + .form-group + = f.label name, class: "control-label" + .col-sm-10 + = f.text_field name, class: "form-control", placeholder: placeholder + + .form-actions + = f.submit 'Save', class: 'btn btn-save' diff --git a/app/views/admin/services/edit.html.haml b/app/views/admin/services/edit.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..bcc5832792fea10b70d29a9fb15633f06e001dd0 --- /dev/null +++ b/app/views/admin/services/edit.html.haml @@ -0,0 +1 @@ += render 'form' diff --git a/app/views/admin/services/index.html.haml b/app/views/admin/services/index.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..1d3e192a325db8d4813e46c0d9d77743aec9b35d --- /dev/null +++ b/app/views/admin/services/index.html.haml @@ -0,0 +1,22 @@ +%h3.page-title Service templates +%p.light Service template allows you to set default values for project services + +%table.table + %thead + %tr + %th + %th Service + %th Desription + %th Last edit + - @services.sort_by(&:title).each do |service| + %tr + %td + = icon("copy", class: 'clgray') + %td + = link_to edit_admin_application_settings_service_path(service.id) do + %strong= service.title + %td + = service.description + %td.light + = time_ago_in_words service.updated_at + ago diff --git a/config/routes.rb b/config/routes.rb index c8a8415ae77aded2361f612bbd286646d9ea9ca1..65786d8356664d05d27dafd845440613ca7a5426 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -51,7 +51,7 @@ Gitlab::Application.routes.draw do end get '/s/:username' => 'snippets#user_index', as: :user_snippets, constraints: { username: /.*/ } - + # # Import # @@ -68,8 +68,8 @@ Gitlab::Application.routes.draw do get :jobs end end - - + + # # Explore area @@ -131,7 +131,9 @@ Gitlab::Application.routes.draw do end end - resource :application_settings, only: [:show, :update] + resource :application_settings, only: [:show, :update] do + resources :services + end root to: 'dashboard#index' end