From 57d001309013c4c27e593778ec68b523e7d73b81 Mon Sep 17 00:00:00 2001
From: Valery Sizov <vsv2711@gmail.com>
Date: Thu, 3 Sep 2015 15:50:23 +0300
Subject: [PATCH] CRUD for admin labels

---
 app/controllers/admin/labels_controller.rb    |  59 +++++++
 app/models/label.rb                           |   8 +-
 app/views/admin/labels/_form.html.haml        |  35 ++++
 app/views/admin/labels/_label.html.haml       |   5 +
 app/views/admin/labels/destroy.js.haml        |   2 +
 app/views/admin/labels/edit.html.haml         |   9 +
 app/views/admin/labels/index.html.haml        |  16 ++
 app/views/admin/labels/new.html.haml          |   7 +
 app/views/layouts/nav/_admin.html.haml        |   6 +
 config/routes.rb                              |   2 +
 .../20150902001023_add_template_to_label.rb   |   5 +
 db/schema.rb                                  | 160 +++++++++++++-----
 12 files changed, 275 insertions(+), 39 deletions(-)
 create mode 100644 app/controllers/admin/labels_controller.rb
 create mode 100644 app/views/admin/labels/_form.html.haml
 create mode 100644 app/views/admin/labels/_label.html.haml
 create mode 100644 app/views/admin/labels/destroy.js.haml
 create mode 100644 app/views/admin/labels/edit.html.haml
 create mode 100644 app/views/admin/labels/index.html.haml
 create mode 100644 app/views/admin/labels/new.html.haml
 create mode 100644 db/migrate/20150902001023_add_template_to_label.rb

diff --git a/app/controllers/admin/labels_controller.rb b/app/controllers/admin/labels_controller.rb
new file mode 100644
index 00000000000..bcdfe6c80a0
--- /dev/null
+++ b/app/controllers/admin/labels_controller.rb
@@ -0,0 +1,59 @@
+
+class Admin::LabelsController < Admin::ApplicationController
+  before_action :set_label, only: [:show, :edit, :update, :destroy]
+
+  def index
+    @labels = Label.templates.page(params[:page]).per(PER_PAGE)
+  end
+
+  def show
+  end
+
+  def new
+    @label = Label.new
+  end
+
+  def edit
+  end
+
+  def create
+    @label = Label.new(label_params)
+    @label.template = true
+
+    if @label.save
+      redirect_to admin_labels_url, notice: "Label was created"
+    else
+      render :new
+    end
+  end
+
+  def update
+    if @label.update(label_params)
+      redirect_to admin_labels_path, notice: 'label was successfully updated.'
+    else
+      render :edit
+    end
+  end
+
+  def destroy
+    @label.destroy
+    @labels = Label.templates
+
+    respond_to do |format|
+      format.html do
+        redirect_to(admin_labels_path, notice: 'Label was removed')
+      end
+      format.js
+    end
+  end
+
+  private
+
+  def set_label
+    @label = Label.find(params[:id])
+  end
+
+  def label_params
+    params[:label].permit(:title, :color)
+  end
+end
diff --git a/app/models/label.rb b/app/models/label.rb
index 230631b5180..4a22bd53400 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -24,7 +24,7 @@ class Label < ActiveRecord::Base
   validates :color,
             format: { with: /\A#[0-9A-Fa-f]{6}\Z/ },
             allow_blank: false
-  validates :project, presence: true
+  validates :project, presence: true, unless: Proc.new { |service| service.template? }
 
   # Don't allow '?', '&', and ',' for label titles
   validates :title,
@@ -34,6 +34,8 @@ class Label < ActiveRecord::Base
 
   default_scope { order(title: :asc) }
 
+  scope :templates, ->  { where(template: true) }
+
   alias_attribute :name, :title
 
   def self.reference_prefix
@@ -78,4 +80,8 @@ class Label < ActiveRecord::Base
   def open_issues_count
     issues.opened.count
   end
+
+  def template?
+    template
+  end
 end
diff --git a/app/views/admin/labels/_form.html.haml b/app/views/admin/labels/_form.html.haml
new file mode 100644
index 00000000000..ad58a3837f6
--- /dev/null
+++ b/app/views/admin/labels/_form.html.haml
@@ -0,0 +1,35 @@
+= form_for [:admin, @label], html: { class: 'form-horizontal label-form js-requires-input' } do |f|
+  -if @label.errors.any?
+    .row
+      .col-sm-offset-2.col-sm-10
+        .alert.alert-danger
+          - @label.errors.full_messages.each do |msg|
+            %span= msg
+            %br
+
+  .form-group
+    = f.label :title, class: 'control-label'
+    .col-sm-10
+      = f.text_field :title, class: "form-control", required: true
+  .form-group
+    = f.label :color, "Background Color", class: 'control-label'
+    .col-sm-10
+      .input-group
+        .input-group-addon.label-color-preview &nbsp;
+        = f.color_field :color, class: "form-control"
+      .help-block
+        Choose any color.
+        %br
+        Or you can choose one of suggested colors below
+
+      .suggest-colors
+        - suggested_colors.each do |color|
+          = link_to '#', style: "background-color: #{color}", data: { color: color } do
+            &nbsp;
+
+  .form-actions
+    = f.submit 'Save', class: 'btn btn-save js-save-button'
+    = link_to "Cancel", admin_labels_path, class: 'btn btn-cancel'
+
+:coffeescript
+  new Labels
diff --git a/app/views/admin/labels/_label.html.haml b/app/views/admin/labels/_label.html.haml
new file mode 100644
index 00000000000..596e06243dd
--- /dev/null
+++ b/app/views/admin/labels/_label.html.haml
@@ -0,0 +1,5 @@
+%li{id: dom_id(label)}
+  = render_colored_label(label)
+  .pull-right
+    = link_to 'Edit', edit_admin_label_path(label), class: 'btn btn-sm'
+    = link_to 'Remove', admin_label_path(label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}
diff --git a/app/views/admin/labels/destroy.js.haml b/app/views/admin/labels/destroy.js.haml
new file mode 100644
index 00000000000..9d51762890f
--- /dev/null
+++ b/app/views/admin/labels/destroy.js.haml
@@ -0,0 +1,2 @@
+- if @labels.size == 0
+  $('.labels').load(document.URL + ' .light-well').hide().fadeIn(1000)
diff --git a/app/views/admin/labels/edit.html.haml b/app/views/admin/labels/edit.html.haml
new file mode 100644
index 00000000000..45c62a76259
--- /dev/null
+++ b/app/views/admin/labels/edit.html.haml
@@ -0,0 +1,9 @@
+- page_title "Edit", @label.name, "Labels"
+%h3
+  Edit label
+  %span.light #{@label.name}
+.back-link
+  = link_to admin_labels_path do
+    &larr; To labels list
+%hr
+= render 'form'
diff --git a/app/views/admin/labels/index.html.haml b/app/views/admin/labels/index.html.haml
new file mode 100644
index 00000000000..8b11c28c56e
--- /dev/null
+++ b/app/views/admin/labels/index.html.haml
@@ -0,0 +1,16 @@
+- page_title "Labels"
+= link_to new_admin_label_path, class: "pull-right btn btn-new" do
+  New label
+%h3.page-title
+  Labels
+%hr
+
+.labels
+  - if @labels.present?
+    %ul.bordered-list.manage-labels-list
+      = render @labels
+    = paginate @labels, theme: 'gitlab'
+  - else
+    .light-well
+      .nothing-here-block There are no any labels yet
+      
\ No newline at end of file
diff --git a/app/views/admin/labels/new.html.haml b/app/views/admin/labels/new.html.haml
new file mode 100644
index 00000000000..8d298ad20f7
--- /dev/null
+++ b/app/views/admin/labels/new.html.haml
@@ -0,0 +1,7 @@
+- page_title "New Label"
+%h3 New label
+.back-link
+  = link_to admin_labels_path do
+    &larr; To labels list
+%hr
+= render 'form'
diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml
index 2065be3828a..3fe0127041e 100644
--- a/app/views/layouts/nav/_admin.html.haml
+++ b/app/views/layouts/nav/_admin.html.haml
@@ -57,6 +57,12 @@
       %span
         Service Templates
 
+  = nav_link(controller: :labels) do
+    = link_to admin_labels_path, title: 'Labels', data: {placement: 'right'} do
+      = icon('tags fw')
+      %span
+        Labels
+
   = nav_link(controller: :abuse_reports) do
     = link_to admin_abuse_reports_path, title: "Abuse reports" do
       = icon('exclamation-circle fw')
diff --git a/config/routes.rb b/config/routes.rb
index 920ece518ea..d93b5f936ab 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -201,6 +201,8 @@ Gitlab::Application.routes.draw do
       resources :services
     end
 
+    resources :labels
+
     root to: 'dashboard#index'
   end
 
diff --git a/db/migrate/20150902001023_add_template_to_label.rb b/db/migrate/20150902001023_add_template_to_label.rb
new file mode 100644
index 00000000000..bd381a97b69
--- /dev/null
+++ b/db/migrate/20150902001023_add_template_to_label.rb
@@ -0,0 +1,5 @@
+class AddTemplateToLabel < ActiveRecord::Migration
+  def change
+    add_column :labels, :template, :boolean, default: false
+  end
+end
\ No newline at end of file
diff --git a/db/schema.rb b/db/schema.rb
index 36568dd4edd..83757a27729 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20150824002011) do
+ActiveRecord::Schema.define(version: 20150902001023) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -24,6 +24,17 @@ ActiveRecord::Schema.define(version: 20150824002011) do
     t.datetime "updated_at"
   end
 
+  create_table "appearances", force: true do |t|
+    t.string   "title"
+    t.text     "description"
+    t.string   "logo"
+    t.integer  "updated_by"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "dark_logo"
+    t.string   "light_logo"
+  end
+
   create_table "application_settings", force: true do |t|
     t.integer  "default_projects_limit"
     t.boolean  "signup_enabled"
@@ -36,17 +47,36 @@ ActiveRecord::Schema.define(version: 20150824002011) do
     t.integer  "default_branch_protection",    default: 2
     t.boolean  "twitter_sharing_enabled",      default: true
     t.text     "restricted_visibility_levels"
-    t.boolean  "version_check_enabled",        default: true
     t.integer  "max_attachment_size",          default: 10,    null: false
     t.integer  "default_project_visibility"
     t.integer  "default_snippet_visibility"
     t.text     "restricted_signup_domains"
+    t.boolean  "version_check_enabled",        default: true
     t.boolean  "user_oauth_applications",      default: true
     t.string   "after_sign_out_path"
     t.integer  "session_expire_delay",         default: 10080, null: false
+    t.text     "help_text"
     t.text     "import_sources"
   end
 
+  create_table "approvals", force: true do |t|
+    t.integer  "merge_request_id", null: false
+    t.integer  "user_id",          null: false
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "approvers", force: true do |t|
+    t.integer  "target_id",   null: false
+    t.string   "target_type"
+    t.integer  "user_id",     null: false
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "approvers", ["target_id", "target_type"], name: "index_approvers_on_target_id_and_target_type", using: :btree
+  add_index "approvers", ["user_id"], name: "index_approvers_on_user_id", using: :btree
+
   create_table "audit_events", force: true do |t|
     t.integer  "author_id",   null: false
     t.string   "type",        null: false
@@ -119,6 +149,28 @@ ActiveRecord::Schema.define(version: 20150824002011) do
 
   add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree
 
+  create_table "git_hooks", force: true do |t|
+    t.string   "force_push_regex"
+    t.string   "delete_branch_regex"
+    t.string   "commit_message_regex"
+    t.boolean  "deny_delete_tag"
+    t.integer  "project_id"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "author_email_regex"
+    t.boolean  "member_check",         default: false, null: false
+    t.string   "file_name_regex"
+    t.boolean  "is_sample",            default: false
+    t.integer  "max_file_size",        default: 0
+  end
+
+  create_table "historical_data", force: true do |t|
+    t.date     "date",              null: false
+    t.integer  "active_user_count"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
   create_table "identities", force: true do |t|
     t.string   "extern_uid"
     t.string   "provider"
@@ -186,10 +238,26 @@ ActiveRecord::Schema.define(version: 20150824002011) do
     t.integer  "project_id"
     t.datetime "created_at"
     t.datetime "updated_at"
+    t.boolean  "template",   default: false
   end
 
   add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree
 
+  create_table "ldap_group_links", force: true do |t|
+    t.string   "cn",           null: false
+    t.integer  "group_access", null: false
+    t.integer  "group_id",     null: false
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "provider"
+  end
+
+  create_table "licenses", force: true do |t|
+    t.text     "data",       null: false
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
   create_table "members", force: true do |t|
     t.integer  "access_level",       null: false
     t.integer  "source_id",          null: false
@@ -271,14 +339,15 @@ ActiveRecord::Schema.define(version: 20150824002011) do
   add_index "milestones", ["project_id"], name: "index_milestones_on_project_id", using: :btree
 
   create_table "namespaces", force: true do |t|
-    t.string   "name",                     null: false
-    t.string   "path",                     null: false
+    t.string   "name",                            null: false
+    t.string   "path",                            null: false
     t.integer  "owner_id"
     t.datetime "created_at"
     t.datetime "updated_at"
     t.string   "type"
-    t.string   "description", default: "", null: false
+    t.string   "description",     default: "",    null: false
     t.string   "avatar"
+    t.boolean  "membership_lock", default: false
   end
 
   add_index "namespaces", ["created_at", "id"], name: "index_namespaces_on_created_at_and_id", using: :btree
@@ -356,6 +425,14 @@ ActiveRecord::Schema.define(version: 20150824002011) do
   add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree
   add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
 
+  create_table "project_group_links", force: true do |t|
+    t.integer  "project_id",                null: false
+    t.integer  "group_id",                  null: false
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.integer  "group_access", default: 30, null: false
+  end
+
   create_table "project_import_data", force: true do |t|
     t.integer "project_id"
     t.text    "data"
@@ -368,25 +445,30 @@ ActiveRecord::Schema.define(version: 20150824002011) do
     t.datetime "created_at"
     t.datetime "updated_at"
     t.integer  "creator_id"
-    t.boolean  "issues_enabled",         default: true,     null: false
-    t.boolean  "wall_enabled",           default: true,     null: false
-    t.boolean  "merge_requests_enabled", default: true,     null: false
-    t.boolean  "wiki_enabled",           default: true,     null: false
+    t.boolean  "issues_enabled",                default: true,     null: false
+    t.boolean  "wall_enabled",                  default: true,     null: false
+    t.boolean  "merge_requests_enabled",        default: true,     null: false
+    t.boolean  "wiki_enabled",                  default: true,     null: false
     t.integer  "namespace_id"
-    t.string   "issues_tracker",         default: "gitlab", null: false
+    t.string   "issues_tracker",                default: "gitlab", null: false
     t.string   "issues_tracker_id"
-    t.boolean  "snippets_enabled",       default: true,     null: false
+    t.boolean  "snippets_enabled",              default: true,     null: false
     t.datetime "last_activity_at"
     t.string   "import_url"
-    t.integer  "visibility_level",       default: 0,        null: false
-    t.boolean  "archived",               default: false,    null: false
+    t.integer  "visibility_level",              default: 0,        null: false
+    t.boolean  "archived",                      default: false,    null: false
     t.string   "avatar"
     t.string   "import_status"
-    t.float    "repository_size",        default: 0.0
-    t.integer  "star_count",             default: 0,        null: false
+    t.float    "repository_size",               default: 0.0
+    t.integer  "star_count",                    default: 0,        null: false
     t.string   "import_type"
     t.string   "import_source"
-    t.integer  "commit_count",           default: 0
+    t.text     "merge_requests_template"
+    t.boolean  "merge_requests_rebase_enabled", default: false
+    t.boolean  "merge_requests_rebase_default", default: true
+    t.integer  "approvals_before_merge",        default: 0,        null: false
+    t.boolean  "reset_approvals_on_push",       default: true
+    t.integer  "commit_count",                  default: 0
   end
 
   add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree
@@ -487,12 +569,12 @@ ActiveRecord::Schema.define(version: 20150824002011) do
   add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
 
   create_table "users", force: true do |t|
-    t.string   "email",                      default: "",    null: false
-    t.string   "encrypted_password",         default: "",    null: false
+    t.string   "email",                       default: "",    null: false
+    t.string   "encrypted_password",          default: "",    null: false
     t.string   "reset_password_token"
     t.datetime "reset_password_sent_at"
     t.datetime "remember_created_at"
-    t.integer  "sign_in_count",              default: 0
+    t.integer  "sign_in_count",               default: 0
     t.datetime "current_sign_in_at"
     t.datetime "last_sign_in_at"
     t.string   "current_sign_in_ip"
@@ -500,22 +582,22 @@ ActiveRecord::Schema.define(version: 20150824002011) do
     t.datetime "created_at"
     t.datetime "updated_at"
     t.string   "name"
-    t.boolean  "admin",                      default: false, null: false
-    t.integer  "projects_limit",             default: 10
-    t.string   "skype",                      default: "",    null: false
-    t.string   "linkedin",                   default: "",    null: false
-    t.string   "twitter",                    default: "",    null: false
+    t.boolean  "admin",                       default: false, null: false
+    t.integer  "projects_limit",              default: 10
+    t.string   "skype",                       default: "",    null: false
+    t.string   "linkedin",                    default: "",    null: false
+    t.string   "twitter",                     default: "",    null: false
     t.string   "authentication_token"
-    t.integer  "theme_id",                   default: 1,     null: false
+    t.integer  "theme_id",                    default: 1,     null: false
     t.string   "bio"
-    t.integer  "failed_attempts",            default: 0
+    t.integer  "failed_attempts",             default: 0
     t.datetime "locked_at"
     t.string   "username"
-    t.boolean  "can_create_group",           default: true,  null: false
-    t.boolean  "can_create_team",            default: true,  null: false
+    t.boolean  "can_create_group",            default: true,  null: false
+    t.boolean  "can_create_team",             default: true,  null: false
     t.string   "state"
-    t.integer  "color_scheme_id",            default: 1,     null: false
-    t.integer  "notification_level",         default: 1,     null: false
+    t.integer  "color_scheme_id",             default: 1,     null: false
+    t.integer  "notification_level",          default: 1,     null: false
     t.datetime "password_expires_at"
     t.integer  "created_by_id"
     t.datetime "last_credential_check_at"
@@ -524,20 +606,21 @@ ActiveRecord::Schema.define(version: 20150824002011) do
     t.datetime "confirmed_at"
     t.datetime "confirmation_sent_at"
     t.string   "unconfirmed_email"
-    t.boolean  "hide_no_ssh_key",            default: false
-    t.string   "website_url",                default: "",    null: false
+    t.boolean  "hide_no_ssh_key",             default: false
+    t.string   "website_url",                 default: "",    null: false
     t.string   "notification_email"
-    t.boolean  "hide_no_password",           default: false
-    t.boolean  "password_automatically_set", default: false
+    t.boolean  "hide_no_password",            default: false
+    t.boolean  "password_automatically_set",  default: false
     t.string   "location"
+    t.string   "public_email",                default: "",    null: false
     t.string   "encrypted_otp_secret"
     t.string   "encrypted_otp_secret_iv"
     t.string   "encrypted_otp_secret_salt"
-    t.boolean  "otp_required_for_login",     default: false, null: false
+    t.boolean  "otp_required_for_login",      default: false, null: false
     t.text     "otp_backup_codes"
-    t.string   "public_email",               default: "",    null: false
-    t.integer  "dashboard",                  default: 0
-    t.integer  "project_view",               default: 0
+    t.integer  "dashboard",                   default: 0
+    t.datetime "admin_email_unsubscribed_at"
+    t.integer  "project_view",                default: 0
   end
 
   add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
@@ -573,6 +656,7 @@ ActiveRecord::Schema.define(version: 20150824002011) do
     t.boolean  "merge_requests_events",   default: false,         null: false
     t.boolean  "tag_push_events",         default: false
     t.boolean  "note_events",             default: false,         null: false
+    t.integer  "group_id"
     t.boolean  "enable_ssl_verification", default: false
   end
 
-- 
2.30.9