diff options
author | Douwe Maan <douwe@gitlab.com> | 2017-03-06 21:13:27 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2017-03-06 21:13:27 +0000 |
commit | d617182a1a6f9b19a8a6d117fa3e507fa2b338a8 (patch) | |
tree | e24db462cfb8ed1854e2203a78d6d22b071232e5 /app | |
parent | f96d5112dca596fb85718b3cca2a7b30b3877207 (diff) | |
parent | b70d151db99d6d64f3514006c4fa6c8142e1b785 (diff) | |
download | gitlab-ce-d617182a1a6f9b19a8a6d117fa3e507fa2b338a8.tar.gz |
Merge branch 'master' into 'rs-carrierwave-db'rs-carrierwave-db
# Conflicts:
# spec/models/group_spec.rb
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/behaviors/bind_in_out.js | 47 | ||||
-rw-r--r-- | app/assets/javascripts/behaviors/toggler_behavior.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/dispatcher.js | 8 | ||||
-rw-r--r-- | app/assets/javascripts/main.js | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/groups.scss | 16 | ||||
-rw-r--r-- | app/controllers/groups_controller.rb | 12 | ||||
-rw-r--r-- | app/models/chat_team.rb | 5 | ||||
-rw-r--r-- | app/models/group.rb | 10 | ||||
-rw-r--r-- | app/models/namespace.rb | 1 | ||||
-rw-r--r-- | app/services/groups/create_service.rb | 15 | ||||
-rw-r--r-- | app/services/mattermost/create_team_service.rb | 14 | ||||
-rw-r--r-- | app/views/groups/_create_chat_team.html.haml | 16 | ||||
-rw-r--r-- | app/views/groups/new.html.haml | 2 | ||||
-rw-r--r-- | app/views/shared/_group_form.html.haml | 3 | ||||
-rw-r--r-- | app/views/shared/icons/_icon_mattermost.svg | 1 |
15 files changed, 148 insertions, 6 deletions
diff --git a/app/assets/javascripts/behaviors/bind_in_out.js b/app/assets/javascripts/behaviors/bind_in_out.js new file mode 100644 index 00000000000..886f127b06b --- /dev/null +++ b/app/assets/javascripts/behaviors/bind_in_out.js @@ -0,0 +1,47 @@ +class BindInOut { + constructor(bindIn, bindOut) { + this.in = bindIn; + this.out = bindOut; + + this.eventWrapper = {}; + this.eventType = /(INPUT|TEXTAREA)/.test(bindIn.tagName) ? 'keyup' : 'change'; + } + + addEvents() { + this.eventWrapper.updateOut = this.updateOut.bind(this); + + this.in.addEventListener(this.eventType, this.eventWrapper.updateOut); + + return this; + } + + updateOut() { + this.out.textContent = this.in.value; + + return this; + } + + removeEvents() { + this.in.removeEventListener(this.eventType, this.eventWrapper.updateOut); + + return this; + } + + static initAll() { + const ins = document.querySelectorAll('*[data-bind-in]'); + + return [].map.call(ins, anIn => BindInOut.init(anIn)); + } + + static init(anIn, anOut) { + const out = anOut || document.querySelector(`*[data-bind-out="${anIn.dataset.bindIn}"]`); + + if (!out) return null; + + const bindInOut = new BindInOut(anIn, out); + + return bindInOut.addEvents().updateOut(); + } +} + +export default BindInOut; diff --git a/app/assets/javascripts/behaviors/toggler_behavior.js b/app/assets/javascripts/behaviors/toggler_behavior.js index a7181904ac9..0726c6c9636 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.js +++ b/app/assets/javascripts/behaviors/toggler_behavior.js @@ -21,8 +21,7 @@ // %a.js-toggle-button // %div.js-toggle-content // - $('body').on('click', '.js-toggle-button', function(e) { - e.preventDefault(); + $('body').on('click', '.js-toggle-button', function() { toggleContainer($(this).closest('.js-toggle-container')); }); diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index ef5785b5532..31f10f89245 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -35,6 +35,7 @@ /* global Labels */ /* global Shortcuts */ +import BindInOut from './behaviors/bind_in_out'; import GroupsList from './groups_list'; import ProjectsList from './projects_list'; @@ -229,9 +230,14 @@ const UserCallout = require('./user_callout'); new UsersSelect(); break; case 'groups:new': + case 'admin:groups:new': + case 'groups:create': + case 'admin:groups:create': + BindInOut.initAll(); + case 'groups:new': + case 'admin:groups:new': case 'groups:edit': case 'admin:groups:edit': - case 'admin:groups:new': new GroupAvatar(); break; case 'projects:tree:show': diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 798553c16ac..6ac659fd290 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -41,6 +41,7 @@ require('./behaviors/details_behavior'); require('./behaviors/quick_submit'); require('./behaviors/requires_input'); require('./behaviors/toggler_behavior'); +require('./behaviors/bind_in_out'); // blob require('./blob/blob_ci_yaml'); diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss index d377526e655..84d21e48463 100644 --- a/app/assets/stylesheets/pages/groups.scss +++ b/app/assets/stylesheets/pages/groups.scss @@ -73,3 +73,19 @@ } } } + +.mattermost-icon svg { + width: 16px; + height: 16px; + vertical-align: text-bottom; +} + +.mattermost-team-name { + color: $gl-text-color-secondary; +} + +.mattermost-info { + display: block; + color: $gl-text-color-secondary; + margin-top: 10px; +} diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 15db5b7762d..4663b6e7fc6 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -32,7 +32,13 @@ class GroupsController < Groups::ApplicationController @group = Groups::CreateService.new(current_user, group_params).execute if @group.persisted? - redirect_to @group, notice: "Group '#{@group.name}' was successfully created." + notice = if @group.chat_team.present? + "Group '#{@group.name}' and its Mattermost team were successfully created." + else + "Group '#{@group.name}' was successfully created." + end + + redirect_to @group, notice: notice else render action: "new" end @@ -142,7 +148,9 @@ class GroupsController < Groups::ApplicationController :request_access_enabled, :share_with_group_lock, :visibility_level, - :parent_id + :parent_id, + :create_chat_team, + :chat_team_name ] end diff --git a/app/models/chat_team.rb b/app/models/chat_team.rb new file mode 100644 index 00000000000..7952141a0d6 --- /dev/null +++ b/app/models/chat_team.rb @@ -0,0 +1,5 @@ +class ChatTeam < ActiveRecord::Base + validates :team_id, presence: true + + belongs_to :namespace +end diff --git a/app/models/group.rb b/app/models/group.rb index a1f12ed55ea..bd0ecae3da4 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -213,4 +213,14 @@ class Group < Namespace def users_with_parents User.where(id: members_with_parents.select(:user_id)) end + + def mattermost_team_params + max_length = 59 + + { + name: path[0..max_length], + display_name: name[0..max_length], + type: public? ? 'O' : 'I' # Open vs Invite-only + } + end end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 3137dd32f93..d350f1d6770 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -20,6 +20,7 @@ class Namespace < ActiveRecord::Base belongs_to :parent, class_name: "Namespace" has_many :children, class_name: "Namespace", foreign_key: :parent_id + has_one :chat_team, dependent: :destroy validates :owner, presence: true, unless: ->(n) { n.type == "Group" } validates :name, diff --git a/app/services/groups/create_service.rb b/app/services/groups/create_service.rb index febeb661fb5..c4e9b8fd8e0 100644 --- a/app/services/groups/create_service.rb +++ b/app/services/groups/create_service.rb @@ -2,6 +2,7 @@ module Groups class CreateService < Groups::BaseService def initialize(user, params = {}) @current_user, @params = user, params.dup + @chat_team = @params.delete(:create_chat_team) end def execute @@ -20,9 +21,23 @@ module Groups end @group.name ||= @group.path.dup + + if create_chat_team? + response = Mattermost::CreateTeamService.new(@group, current_user).execute + return @group if @group.errors.any? + + @group.build_chat_team(name: response['name'], team_id: response['id']) + end + @group.save @group.add_owner(current_user) @group end + + private + + def create_chat_team? + Gitlab.config.mattermost.enabled && @chat_team && group.chat_team.nil? + end end end diff --git a/app/services/mattermost/create_team_service.rb b/app/services/mattermost/create_team_service.rb new file mode 100644 index 00000000000..e3206810f3a --- /dev/null +++ b/app/services/mattermost/create_team_service.rb @@ -0,0 +1,14 @@ +module Mattermost + class CreateTeamService < ::BaseService + def initialize(group, current_user) + @group, @current_user = group, current_user + end + + def execute + # The user that creates the team will be Team Admin + Mattermost::Team.new(current_user).create(@group.mattermost_team_params) + rescue Mattermost::ClientError => e + @group.errors.add(:mattermost_team, e.message) + end + end +end diff --git a/app/views/groups/_create_chat_team.html.haml b/app/views/groups/_create_chat_team.html.haml new file mode 100644 index 00000000000..20de1b4c973 --- /dev/null +++ b/app/views/groups/_create_chat_team.html.haml @@ -0,0 +1,16 @@ +.form-group + = f.label :create_chat_team, class: 'control-label' do + %span.mattermost-icon + = custom_icon('icon_mattermost') + Mattermost + .col-sm-10 + .checkbox.js-toggle-container + = f.label :create_chat_team do + .js-toggle-button= f.check_box(:create_chat_team, { checked: true }, true, false) + Create a Mattermost team for this group + %br + %small.light.js-toggle-content + Mattermost URL: + = Settings.mattermost.host + %span> / + %span{ "data-bind-out" => "create_chat_team" } diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml index 38d63fd9acc..000c7af2326 100644 --- a/app/views/groups/new.html.haml +++ b/app/views/groups/new.html.haml @@ -16,6 +16,8 @@ = render 'shared/visibility_level', f: f, visibility_level: default_group_visibility, can_change_visibility_level: true, form_model: @group + = render 'create_chat_team', f: f if Gitlab.config.mattermost.enabled + .form-group .col-sm-offset-2.col-sm-10 = render 'shared/group_tips' diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml index 02b7b2447ed..c2d9ac87b20 100644 --- a/app/views/shared/_group_form.html.haml +++ b/app/views/shared/_group_form.html.haml @@ -18,7 +18,8 @@ = f.text_field :path, placeholder: 'open-source', class: 'form-control', autofocus: local_assigns[:autofocus] || false, required: true, pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_JS, - title: 'Please choose a group name with no special characters.' + title: 'Please choose a group name with no special characters.', + "data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}" - if parent = f.hidden_field :parent_id, value: parent.id diff --git a/app/views/shared/icons/_icon_mattermost.svg b/app/views/shared/icons/_icon_mattermost.svg new file mode 100644 index 00000000000..d1c541523ab --- /dev/null +++ b/app/views/shared/icons/_icon_mattermost.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><path d="M250.05 34c1.9.04 3.8.11 5.6.2l-29.79 35.51c-.07.01-.15.03-.23.04C149.26 84.1 98.22 146.5 98.22 222.97c0 41.56 23.07 90.5 59.75 119.1 28.61 22.32 64.29 36.9 101.21 36.9 93.4 0 160.15-68.61 160.15-156 0-34.91-15.99-72.77-41.76-100.76l-1.63-47.39c54.45 39.15 89.95 103.02 90.06 175.17v.01c0 119.29-96.7 216-216 216-119.29 0-216-96.71-216-216S130.71 34 250 34h.05zm64.1 20.29c.66-.04 1.32.03 1.96.25 3.01 1 3.85 3.57 3.93 6.45l3.84 146.88c.76 28.66-17.16 68.44-60.39 68.56-30.97.08-63.68-20.83-63.68-60.13.01-14.73 5.61-31.26 19.25-48.11l90.03-111.18c1.15-1.42 3.08-2.58 5.06-2.72z"/></svg> |