From 3655e433dd697998578b03dc57191a412f505f5a Mon Sep 17 00:00:00 2001 From: Rowan Wookey Date: Mon, 24 Aug 2015 23:06:48 +0100 Subject: Fixed #1952 docker ssh connection times can be slow when UseDNS is enabled --- CHANGELOG | 1 + docker/Dockerfile | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 5940d586d88..7816430a208 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,7 @@ v 8.0.0 (unreleased) - Search for comments should be case insensetive - Create cross-reference for closing references on commits pushed to non-default branches (MaĆ«l Valais) - Ability to search milestones + - Disabled DNS lookups for SSH in docker image (Rowan Wookey) v 7.14.1 (unreleased) - Only include base URL in OmniAuth full_host parameter (Stan Hu) diff --git a/docker/Dockerfile b/docker/Dockerfile index 05521af6963..304bb97409e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -25,6 +25,9 @@ RUN mkdir -p /opt/gitlab/sv/sshd/supervise \ && ln -s /opt/gitlab/sv/sshd /opt/gitlab/service \ && mkdir -p /var/run/sshd +# Disabling use DNS in ssh since it tends to slow connecting +RUN echo "UseDNS no" >> /etc/ssh/sshd_config + # Prepare default configuration RUN ( \ echo "" && \ -- cgit v1.2.1 From 57d001309013c4c27e593778ec68b523e7d73b81 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 3 Sep 2015 15:50:23 +0300 Subject: 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 + db/migrate/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   + = 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 +   + + .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 + ← 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 + ← 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 -- cgit v1.2.1 From f5ffeac058260de26efdcdae4205804154bc027e Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 3 Sep 2015 17:12:15 +0300 Subject: Create labels in new project --- CHANGELOG | 1 + app/models/project.rb | 9 +++++++++ app/services/projects/create_service.rb | 2 ++ 3 files changed, 12 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index e46fb5d6c1e..276a221971d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -35,6 +35,7 @@ v 8.0.0 (unreleased) - Added Drone CI integration (Kirill Zaitsev) - Refactored service API and added automatically service docs generator (Kirill Zaitsev) - Added web_url key project hook_attrs (Kirill Zaitsev) + - Global Labels that are available to all projects v 7.14.1 - Improve abuse reports management from admin area diff --git a/app/models/project.rb b/app/models/project.rb index 8e33a4b2f0f..bdedd7aa9e0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -401,6 +401,15 @@ class Project < ActiveRecord::Base end end + def create_labels + Label.templates.each do |label| + label = label.dup + label.template = nil + label.project_id = self.id + label.save + end + end + def find_service(list, name) list.find { |service| service.to_param == name } end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index b35aed005da..1bb2462565a 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -87,6 +87,8 @@ module Projects @project.build_missing_services + @project.create_labels + event_service.create_project(@project, current_user) system_hook_service.execute_hooks_for(@project, :create) -- cgit v1.2.1 From 6bd3d72bbdf288ecf2eee718f2943821c1401a22 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Thu, 3 Sep 2015 18:44:58 +0300 Subject: added spinach for glabal labels --- app/controllers/admin/labels_controller.rb | 1 - db/schema.rb | 157 ++++++-------------------- features/admin/labels.feature | 38 +++++++ features/steps/admin/labels.rb | 117 +++++++++++++++++++ spec/services/projects/create_service_spec.rb | 8 ++ 5 files changed, 200 insertions(+), 121 deletions(-) create mode 100644 features/admin/labels.feature create mode 100644 features/steps/admin/labels.rb diff --git a/app/controllers/admin/labels_controller.rb b/app/controllers/admin/labels_controller.rb index bcdfe6c80a0..3b070e65d0d 100644 --- a/app/controllers/admin/labels_controller.rb +++ b/app/controllers/admin/labels_controller.rb @@ -1,4 +1,3 @@ - class Admin::LabelsController < Admin::ApplicationController before_action :set_label, only: [:show, :edit, :update, :destroy] diff --git a/db/schema.rb b/db/schema.rb index 83757a27729..55cbd8c293e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -24,17 +24,6 @@ ActiveRecord::Schema.define(version: 20150902001023) 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" @@ -47,36 +36,17 @@ ActiveRecord::Schema.define(version: 20150902001023) 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 @@ -149,28 +119,6 @@ ActiveRecord::Schema.define(version: 20150902001023) 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" @@ -243,21 +191,6 @@ ActiveRecord::Schema.define(version: 20150902001023) do 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 @@ -339,15 +272,14 @@ ActiveRecord::Schema.define(version: 20150902001023) 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 @@ -425,14 +357,6 @@ ActiveRecord::Schema.define(version: 20150902001023) 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" @@ -445,30 +369,25 @@ ActiveRecord::Schema.define(version: 20150902001023) 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.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 + t.integer "commit_count", default: 0 end add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree @@ -569,12 +488,12 @@ ActiveRecord::Schema.define(version: 20150902001023) 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" @@ -582,22 +501,22 @@ ActiveRecord::Schema.define(version: 20150902001023) 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" @@ -606,21 +525,20 @@ ActiveRecord::Schema.define(version: 20150902001023) 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.integer "dashboard", default: 0 - t.datetime "admin_email_unsubscribed_at" - t.integer "project_view", default: 0 + t.string "public_email", default: "", null: false + t.integer "dashboard", default: 0 + t.integer "project_view", default: 0 end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree @@ -656,7 +574,6 @@ ActiveRecord::Schema.define(version: 20150902001023) 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 diff --git a/features/admin/labels.feature b/features/admin/labels.feature new file mode 100644 index 00000000000..1af0e700bd4 --- /dev/null +++ b/features/admin/labels.feature @@ -0,0 +1,38 @@ +Feature: Admin Issues Labels + Background: + Given I sign in as an admin + And I have labels: "bug", "feature", "enhancement" + Given I visit admin labels page + + Scenario: I should see labels list + Then I should see label 'bug' + And I should see label 'feature' + + Scenario: I create new label + Given I submit new label 'support' + Then I should see label 'support' + + Scenario: I edit label + Given I visit 'bug' label edit page + When I change label 'bug' to 'fix' + Then I should not see label 'bug' + Then I should see label 'fix' + + Scenario: I remove label + When I remove label 'bug' + Then I should not see label 'bug' + + @javascript + Scenario: I delete all labels + When I delete all labels + Then I should see labels help message + + Scenario: I create a label with invalid color + Given I visit admin new label page + When I submit new label with invalid color + Then I should see label color error message + + Scenario: I create a label that already exists + Given I visit admin new label page + When I submit new label 'bug' + Then I should see label exist error message diff --git a/features/steps/admin/labels.rb b/features/steps/admin/labels.rb new file mode 100644 index 00000000000..d64380abf73 --- /dev/null +++ b/features/steps/admin/labels.rb @@ -0,0 +1,117 @@ +class Spinach::Features::AdminIssuesLabels < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I visit \'bug\' label edit page' do + visit edit_admin_label_path(bug_label) + end + + step 'I visit admin new label page' do + visit new_admin_label_path + end + + step 'I visit admin labels page' do + visit admin_labels_path + end + + step 'I remove label \'bug\'' do + page.within "#label_#{bug_label.id}" do + click_link 'Remove' + end + end + + step 'I have labels: "bug", "feature", "enhancement"' do + ["bug", "feature", "enhancement"].each do |title| + Label.create(title: title, template: true) + end + end + + step 'I delete all labels' do + page.within '.labels' do + page.all('.btn-remove').each do |remove| + remove.click + sleep 0.05 + end + end + end + + step 'I should see labels help message' do + page.within '.labels' do + expect(page).to have_content 'There are no any labels yet' + end + end + + step 'I submit new label \'support\'' do + visit new_admin_label_path + fill_in 'Title', with: 'support' + fill_in 'Background Color', with: '#F95610' + click_button 'Save' + end + + step 'I submit new label \'bug\'' do + visit new_admin_label_path + fill_in 'Title', with: 'bug' + fill_in 'Background Color', with: '#F95610' + click_button 'Save' + end + + step 'I submit new label with invalid color' do + visit new_admin_label_path + fill_in 'Title', with: 'support' + fill_in 'Background Color', with: '#12' + click_button 'Save' + end + + step 'I should see label exist error message' do + page.within '.label-form' do + expect(page).to have_content 'Title has already been taken' + end + end + + step 'I should see label color error message' do + page.within '.label-form' do + expect(page).to have_content 'Color is invalid' + end + end + + step 'I should see label \'feature\'' do + page.within '.manage-labels-list' do + expect(page).to have_content 'feature' + end + end + + step 'I should see label \'bug\'' do + page.within '.manage-labels-list' do + expect(page).to have_content 'bug' + end + end + + step 'I should not see label \'bug\'' do + page.within '.manage-labels-list' do + expect(page).not_to have_content 'bug' + end + end + + step 'I should see label \'support\'' do + page.within '.manage-labels-list' do + expect(page).to have_content 'support' + end + end + + step 'I change label \'bug\' to \'fix\'' do + fill_in 'Title', with: 'fix' + fill_in 'Background Color', with: '#F15610' + click_button 'Save' + end + + step 'I should see label \'fix\'' do + page.within '.manage-labels-list' do + expect(page).to have_content 'fix' + end + end + + def bug_label + Label.templates.find_or_create_by(title: 'bug') + end +end diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index 66cdfd5d758..ff4ed2dd484 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -17,6 +17,14 @@ describe Projects::CreateService do expect(project.services).not_to be_empty end + it 'creates labels on Project creation if there are templates' do + Label.create(title: "bug", template: true) + project = create_project(@user, @opts) + project.reload + + expect(project.labels).not_to be_empty + end + context 'user namespace' do before do @project = create_project(@user, @opts) -- cgit v1.2.1 From 8820785c8fe267789a5c6edf7f4fcb196c48b4a8 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 6 Sep 2015 09:42:39 -0700 Subject: Fix emoji URLs in Markdown when relative_url_root is used Also adds the ability to run rspecs with relative_url_defined on the enviornment. For example: RELATIVE_URL_ROOT=/gitlab rspec Closes #1728 --- CHANGELOG | 1 + lib/gitlab/markdown.rb | 2 +- spec/spec_helper.rb | 1 + spec/support/matchers/markdown_matchers.rb | 3 +++ spec/support/relative_url.rb | 8 ++++++++ 5 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 spec/support/relative_url.rb diff --git a/CHANGELOG b/CHANGELOG index 8154d4333d9..329ce74a5d5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.0.0 (unreleased) + - Fix emoji URLs in Markdown when relative_url_root is used (Stan Hu) - Omit filename in Content-Disposition header in raw file download to avoid RFC 6266 encoding issues (Stan HU) - Prevent anchors from being hidden by header (Stan Hu) - Fix bug where only the first 15 Bitbucket issues would be imported (Stan Hu) diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 097caf67a65..ae5f2544691 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -77,7 +77,7 @@ module Gitlab pipeline: options[:pipeline], # EmojiFilter - asset_root: Gitlab.config.gitlab.url, + asset_root: Gitlab.config.gitlab.base_url, asset_host: Gitlab::Application.config.asset_host, # TableOfContentsFilter diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d0f1873ee2d..0780c4f3203 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -28,6 +28,7 @@ RSpec.configure do |config| config.include LoginHelpers, type: :feature config.include LoginHelpers, type: :request config.include StubConfiguration + config.include RelativeUrl, type: feature config.include TestEnv config.infer_spec_type_from_file_location! diff --git a/spec/support/matchers/markdown_matchers.rb b/spec/support/matchers/markdown_matchers.rb index 9df226c3af8..7500d0fdf80 100644 --- a/spec/support/matchers/markdown_matchers.rb +++ b/spec/support/matchers/markdown_matchers.rb @@ -27,6 +27,9 @@ module MarkdownMatchers match do |actual| expect(actual).to have_selector('img.emoji', count: 10) + + image = actual.at_css('img.emoji') + expect(image['src'].to_s).to start_with(Gitlab.config.gitlab.url + '/assets') end end diff --git a/spec/support/relative_url.rb b/spec/support/relative_url.rb new file mode 100644 index 00000000000..72e3ccce75b --- /dev/null +++ b/spec/support/relative_url.rb @@ -0,0 +1,8 @@ +# Fix route helpers in tests (e.g. root_path, ...) +module RelativeUrl + extend ActiveSupport::Concern + + included do + default_url_options[:script_name] = Rails.application.config.relative_url_root + end +end -- cgit v1.2.1 From 8d59b1ac456575496e0bceb6812c59545b1e9b50 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 7 Sep 2015 13:05:29 +0200 Subject: Do not let NGINX buffer Git HTTP requests Before this change NGINX would convert a chunked HTTP POST (e.g. git push) into a HTTP 1.0 single large POST. This creates an unnecessary delay, and it creates unnecessary memory pressure on gitlab-git-http-server. For the response ('proxy_buffering') I am less sure that NGINX 's buffering behavior is harmful, but it still makes more sense to me not to interfere with gitlab-git-http-server (and the Golang net/http server). --- lib/support/nginx/gitlab | 7 +++++++ lib/support/nginx/gitlab-ssl | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 17f89c8beb6..1cd81ea769f 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -124,6 +124,13 @@ server { proxy_connect_timeout 300; proxy_redirect off; + # Do not buffer Git HTTP responses + proxy_buffering off; + + # Pass chunked request bodies to gitlab-git-http-server as-is + proxy_request_buffering off; + proxy_http_version 1.1; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 5ba39fc41a4..83aad321aab 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -171,6 +171,13 @@ server { proxy_connect_timeout 300; proxy_redirect off; + # Do not buffer Git HTTP responses + proxy_buffering off; + + # Pass chunked request bodies to gitlab-git-http-server as-is + proxy_request_buffering off; + proxy_http_version 1.1; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Ssl on; -- cgit v1.2.1 From 783791fd08e8144a2ab97307a12df9d2a40e0421 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 7 Sep 2015 14:59:32 +0200 Subject: The good stuff needs NGINX 1.7.11 --- lib/support/nginx/gitlab | 8 +++++--- lib/support/nginx/gitlab-ssl | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 1cd81ea769f..7218a4d2f20 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -127,9 +127,11 @@ server { # Do not buffer Git HTTP responses proxy_buffering off; - # Pass chunked request bodies to gitlab-git-http-server as-is - proxy_request_buffering off; - proxy_http_version 1.1; + # The following settings only work with NGINX 1.7.11 or newer + # + # # Pass chunked request bodies to gitlab-git-http-server as-is + # proxy_request_buffering off; + # proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 83aad321aab..7dabfba87e2 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -174,9 +174,11 @@ server { # Do not buffer Git HTTP responses proxy_buffering off; - # Pass chunked request bodies to gitlab-git-http-server as-is - proxy_request_buffering off; - proxy_http_version 1.1; + # The following settings only work with NGINX 1.7.11 or newer + # + # # Pass chunked request bodies to gitlab-git-http-server as-is + # proxy_request_buffering off; + # proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; -- cgit v1.2.1 From 243bfc975eb670f56e9a7179533c86bfd605104d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 7 Sep 2015 22:04:23 +0200 Subject: Small restyle of issue and merge request pages Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/base/gl_variables.scss | 4 +++ app/assets/stylesheets/generic/blocks.scss | 5 ++++ app/assets/stylesheets/generic/issue_box.scss | 9 ++++-- app/assets/stylesheets/pages/issuable.scss | 19 ++++++++++++ app/views/projects/issues/show.html.haml | 34 +++++++++++----------- app/views/projects/merge_requests/_show.html.haml | 4 +-- .../projects/merge_requests/show/_mr_box.html.haml | 21 ++++++------- .../merge_requests/show/_mr_title.html.haml | 9 +++--- 8 files changed, 68 insertions(+), 37 deletions(-) diff --git a/app/assets/stylesheets/base/gl_variables.scss b/app/assets/stylesheets/base/gl_variables.scss index 6d3b4b1e73a..2447ee21898 100644 --- a/app/assets/stylesheets/base/gl_variables.scss +++ b/app/assets/stylesheets/base/gl_variables.scss @@ -22,6 +22,10 @@ $brand-info: $gl-info; $brand-warning: $gl-warning; $brand-danger: $gl-danger; +$border-radius-base: 3px !default; +$border-radius-large: 5px !default; +$border-radius-small: 2px !default; + //== Scaffolding // diff --git a/app/assets/stylesheets/generic/blocks.scss b/app/assets/stylesheets/generic/blocks.scss index abf4657dd58..27a4c4db8c8 100644 --- a/app/assets/stylesheets/generic/blocks.scss +++ b/app/assets/stylesheets/generic/blocks.scss @@ -27,6 +27,11 @@ border-bottom: 1px solid #e7e9ed; color: $gl-gray; + &.middle-block { + margin-top: 0; + margin-bottom: 0; + } + &.second-block { margin-top: -1px; margin-bottom: 0; diff --git a/app/assets/stylesheets/generic/issue_box.scss b/app/assets/stylesheets/generic/issue_box.scss index 869e586839b..b1fb87a6830 100644 --- a/app/assets/stylesheets/generic/issue_box.scss +++ b/app/assets/stylesheets/generic/issue_box.scss @@ -5,10 +5,13 @@ */ .issue-box { + @include border-radius(3px); + display: inline-block; - padding: 4px 13px; + padding: 10px $gl-padding; font-weight: normal; - margin-right: 5px; + margin-right: 10px; + font-size: $gl-font-size; &.issue-box-closed { background-color: $gl-danger; @@ -21,7 +24,7 @@ } &.issue-box-open { - background-color: $gl-success; + background-color: #019875; color: #FFF; } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 2d32d82e107..afcbc2d9976 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -56,3 +56,22 @@ text-align: left; } } + +.issuable-details { + .page-title { + margin-top: -15px; + padding: 10px 0; + margin-bottom: 0; + color: $gl-gray; + font-size: 16px; + + .author { + color: $gl-gray; + } + + .issue-id { + font-size: 19px; + color: $gl-text-color; + } + } +} diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index e7b14e7582c..6ed472f2d98 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -1,15 +1,16 @@ - page_title "#{@issue.title} (##{@issue.iid})", "Issues" .issue .issue-details.issuable-details - %h4.page-title + .page-title .issue-box{ class: issue_box_class(@issue) } - if @issue.closed? Closed - else Open - Issue ##{@issue.iid} - %small.creator - · created by #{link_to_member(@project, @issue.author)} + %span.issue-id Issue ##{@issue.iid} + %span.creator + · created by #{link_to_member(@project, @issue.author, size: 24)} + · = time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago') - if @issue.updated_at != @issue.created_at %span @@ -32,18 +33,17 @@ = icon('pencil-square-o') Edit - %hr - %h2.issue-title - = gfm escape_once(@issue.title) - %div - - if @issue.description.present? - .description{class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : ''} - .wiki - = preserve do - = markdown(@issue.description) - %textarea.hidden.js-task-list-field - = @issue.description + .gray-content-block.middle-block + %h2.issue-title + = gfm escape_once(@issue.title) + %div + - if @issue.description.present? + .description{class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : ''} + .wiki + = preserve do + = markdown(@issue.description) + %textarea.hidden.js-task-list-field + = @issue.description - %hr - .issue-discussion + .issue-discussion.prepend-top-default = render 'projects/issues/discussion' diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index ec1838eb489..516e5e3ffc0 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -5,10 +5,8 @@ .merge-request{'data-url' => merge_request_path(@merge_request)} .merge-request-details.issuable-details = render "projects/merge_requests/show/mr_title" - %hr = render "projects/merge_requests/show/mr_box" - %hr - .append-bottom-20.mr-source-target + .append-bottom-20.mr-source-target.prepend-top-default - if @merge_request.open? .pull-right - if @merge_request.source_branch_exists? diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index e3cd4346872..b4f62a75890 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -1,11 +1,12 @@ -%h2.issue-title - = gfm escape_once(@merge_request.title) +.gray-content-block.middle-block + %h2.issue-title + = gfm escape_once(@merge_request.title) -%div - - if @merge_request.description.present? - .description{class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : ''} - .wiki - = preserve do - = markdown(@merge_request.description) - %textarea.hidden.js-task-list-field - = @merge_request.description + %div + - if @merge_request.description.present? + .description{class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : ''} + .wiki + = preserve do + = markdown(@merge_request.description) + %textarea.hidden.js-task-list-field + = @merge_request.description diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index 9a1eb36fc88..2bf9cd597a4 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -1,10 +1,11 @@ -%h4.page-title +.page-title .issue-box{ class: issue_box_class(@merge_request) } = @merge_request.state_human_name - Merge Request ##{@merge_request.iid} - %small.creator + %span.issue-id Merge Request ##{@merge_request.iid} + %span.creator + · + created by #{link_to_member(@project, @merge_request.author, size: 24)} · - created by #{link_to_member(@project, @merge_request.author)} = time_ago_with_tooltip(@merge_request.created_at) - if @merge_request.updated_at != @merge_request.created_at %span -- cgit v1.2.1 From 6887075b2eed6115277173dd14b812bb79cf322a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 01:25:51 +0200 Subject: Style issue page, comments and part of merge request page Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/base/mixins.scss | 38 ++++++++- app/assets/stylesheets/generic/common.scss | 32 +------- app/assets/stylesheets/generic/timeline.scss | 95 +++++----------------- app/assets/stylesheets/pages/issues.scss | 4 - app/assets/stylesheets/pages/merge_requests.scss | 17 +--- app/assets/stylesheets/pages/note_form.scss | 10 ++- app/views/projects/issues/_discussion.html.haml | 23 +++--- app/views/projects/issues/show.html.haml | 2 +- .../projects/merge_requests/_discussion.html.haml | 17 ++-- app/views/projects/merge_requests/_show.html.haml | 2 +- 10 files changed, 96 insertions(+), 144 deletions(-) diff --git a/app/assets/stylesheets/base/mixins.scss b/app/assets/stylesheets/base/mixins.scss index 8698109bc4c..0f661d6b1b6 100644 --- a/app/assets/stylesheets/base/mixins.scss +++ b/app/assets/stylesheets/base/mixins.scss @@ -177,7 +177,7 @@ margin: 0px; &:last-child { - border:none + border-bottom: none; } &.active { @@ -215,3 +215,39 @@ font-size: 16px; line-height: 24px; } + +@mixin nav-menu { + padding: 0; + margin: 0; + list-style: none; + margin-top: 5px; + height: 56px; + + li { + display: inline-block; + + a { + padding: 14px; + font-size: 17px; + line-height: 28px; + color: #7f8fa4; + border-bottom: 2px solid transparent; + + &:hover, &:active, &:focus { + text-decoration: none; + } + } + + &.active a { + color: #4c4e54; + border-bottom: 2px solid #1cacfc; + } + + .badge { + font-weight: normal; + background-color: #fff; + background-color: #eee; + color: #78a; + } + } +} diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index b995486588f..5e191d5dd4a 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -370,41 +370,11 @@ table { } .center-top-menu { - padding: 0; - margin: 0; - list-style: none; + @include nav-menu; text-align: center; margin-top: 5px; margin-bottom: $gl-padding; height: 56px; margin-top: -$gl-padding; padding-top: $gl-padding; - - li { - display: inline-block; - - a { - padding: 14px; - font-size: 17px; - line-height: 28px; - color: #7f8fa4; - border-bottom: 2px solid transparent; - - &:hover, &:active, &:focus { - text-decoration: none; - } - } - - &.active a { - color: #4c4e54; - border-bottom: 2px solid #1cacfc; - } - - .badge { - font-weight: normal; - background-color: #fff; - background-color: #eee; - color: #78a; - } - } } diff --git a/app/assets/stylesheets/generic/timeline.scss b/app/assets/stylesheets/generic/timeline.scss index 97831eb7c27..54dc4c52418 100644 --- a/app/assets/stylesheets/generic/timeline.scss +++ b/app/assets/stylesheets/generic/timeline.scss @@ -1,89 +1,38 @@ .timeline { - list-style: none; - padding: 20px 0 20px; - position: relative; + @include basic-list; - &:before { - top: 0; - bottom: 0; - position: absolute; - content: " "; - width: 3px; - background-color: #eeeeee; - margin-left: 29px; - } - - .timeline-entry { - position: relative; - margin-top: 5px; - margin-left: 30px; - margin-bottom: 10px; - clear: both; + margin: 0; + padding: 0; + > li { + padding: $gl-padding; + border-color: #f1f2f4; + margin-left: -$gl-padding; + margin-right: -$gl-padding; + color: $gl-gray; + border-right: 1px solid #f1f2f4; - &:target { - .timeline-entry-inner .timeline-content { - -webkit-animation:target-note 2s linear; - background: $hover; - } + .avatar { + margin-right: 15px; } - .timeline-entry-inner { - position: relative; - margin-left: -20px; - - &:before, &:after { - content: " "; - display: table; - } - - .timeline-icon { - margin-top: 2px; - background: #fff; - color: #737881; - float: left; - @include border-radius($avatar_radius); - @include box-shadow(0 0 0 3px #EEE); - overflow: hidden; - - .avatar { - margin: 0; - padding: 0; - } - } - - .timeline-content { - position: relative; - background: $background-color; - padding: 10px 15px; - margin-left: 60px; - - img { - max-width: 100%; - } + .controls { + padding-top: 10px; + float: right; + } + } - &:after { - content: ''; - display: block; - position: absolute; - width: 0; - height: 0; - border-style: solid; - border-width: 9px 9px 9px 0; - border-color: transparent $background-color transparent transparent; - left: 0; - top: 10px; - margin-left: -9px; - } - } + .note-text { + p:last-child { + margin-bottom: 0; } } .system-note .timeline-entry-inner { .timeline-icon { - background: none; + float: left; margin-left: 12px; - margin-top: 0; + margin-top: 8px; @include box-shadow(none); span { diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 7928b6220fc..c407d53118e 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -47,10 +47,6 @@ } } -.participants { - margin-bottom: 20px; -} - .issue-search-form { margin: 0; height: 24px; diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index f0fb68d3422..d5ede5349d1 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -89,20 +89,11 @@ } } -@media(min-width: $screen-sm-max) { - .merge-request .merge-request-tabs{ - li { - a { - padding: 15px 40px; - font-size: 14px; - } - } - } -} - .merge-request .merge-request-tabs{ - margin-top: 30px; - margin-bottom: 20px; + @include nav-menu; + margin-bottom: -15px; + margin-top: 26px; + text-align: left; } .mr_source_commit, diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 203f9374cee..85804f5ee61 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -72,9 +72,13 @@ .common-note-form { margin: 0; - background: #F9F9F9; - padding: 5px; - border: 1px solid #DDD; + background: #f8fafc; + padding: $gl-padding; + margin-left: -$gl-padding; + margin-right: -$gl-padding; + border-right: 1px solid #f1f2f4; + border-top: 1px solid #f1f2f4; + margin-bottom: -$gl-padding; } .note-form-actions { diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml index f61ae957208..d4a98eca473 100644 --- a/app/views/projects/issues/_discussion.html.haml +++ b/app/views/projects/issues/_discussion.html.haml @@ -7,21 +7,24 @@ = render 'shared/show_aside' +.gray-content-block.second-block + .row + .col-md-9 + .votes-holder.pull-right + #votes= render 'votes/votes_block', votable: @issue + .participants + %span= pluralize(@participants.count, 'participant') + - @participants.each do |participant| + = link_to_member(@project, participant, name: false, size: 24) + .col-md-3 + %span.slead.has_tooltip{title: 'Cross-project reference'} + = cross_project_reference(@project, @issue) + .row %section.col-md-9 - .votes-holder.pull-right - #votes= render 'votes/votes_block', votable: @issue - .participants - %span= pluralize(@participants.count, 'participant') - - @participants.each do |participant| - = link_to_member(@project, participant, name: false, size: 24) .voting_notes#notes= render 'projects/notes/notes_with_form' %aside.col-md-3 .issuable-affix - .clearfix - %span.slead.has_tooltip{title: 'Cross-project reference'} - = cross_project_reference(@project, @issue) - %hr .context = render 'shared/issuable/context', issuable: @issue diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 6ed472f2d98..09080642293 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -45,5 +45,5 @@ %textarea.hidden.js-task-list-field = @issue.description - .issue-discussion.prepend-top-default + .issue-discussion = render 'projects/issues/discussion' diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml index f855dfec321..38e66c3828b 100644 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ b/app/views/projects/merge_requests/_discussion.html.haml @@ -7,18 +7,21 @@ = render 'shared/show_aside' +.gray-content-block.second-block + .row + .col-md-9 + .votes-holder.pull-right + #votes= render 'votes/votes_block', votable: @merge_request + = render "projects/merge_requests/show/participants" + .col-md-3 + %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} + = cross_project_reference(@project, @merge_request) + .row %section.col-md-9 - .votes-holder.pull-right - #votes= render 'votes/votes_block', votable: @merge_request - = render "projects/merge_requests/show/participants" = render "projects/notes/notes_with_form" %aside.col-md-3 .issuable-affix - .clearfix - %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} - = cross_project_reference(@project, @merge_request) - %hr .context = render 'shared/issuable/context', issuable: @merge_request diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 516e5e3ffc0..721993fb279 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -37,7 +37,7 @@ = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" - if @commits.present? - %ul.nav.nav-tabs.merge-request-tabs + %ul.merge-request-tabs %li.notes-tab = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#notes', action: 'notes', toggle: 'tab'} do = icon('comments') -- cgit v1.2.1 From 31fc6b26d845c938b98bd34ddd4648b89572b4ca Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 01:47:36 +0200 Subject: Style comment form Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/generic/markdown_area.scss | 7 +++++-- app/assets/stylesheets/generic/zen.scss | 4 ++-- app/assets/stylesheets/pages/issuable.scss | 10 +--------- app/views/projects/_md_preview.html.haml | 4 ++-- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/generic/markdown_area.scss b/app/assets/stylesheets/generic/markdown_area.scss index a4fc82e90bf..2dcff516e83 100644 --- a/app/assets/stylesheets/generic/markdown_area.scss +++ b/app/assets/stylesheets/generic/markdown_area.scss @@ -65,8 +65,11 @@ position: relative; } -.md-header ul { - float: left; +.md-header { + ul { + float: left; + margin-bottom: 1px; + } } .referenced-users { diff --git a/app/assets/stylesheets/generic/zen.scss b/app/assets/stylesheets/generic/zen.scss index 7e86a0fe4b9..32e2c020e06 100644 --- a/app/assets/stylesheets/generic/zen.scss +++ b/app/assets/stylesheets/generic/zen.scss @@ -4,7 +4,7 @@ } .zen-enter-link { - color: #888; + color: $gl-gray; position: absolute; top: 0px; right: 4px; @@ -13,7 +13,7 @@ .zen-leave-link { display: none; - color: #888; + color: $gl-text-color; position: absolute; top: 10px; right: 10px; diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index afcbc2d9976..e13c8f9eb98 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -25,8 +25,6 @@ } .issuable-context-title { - font-size: 14px; - line-height: 1.4; margin-bottom: 5px; .avatar { @@ -34,18 +32,12 @@ } label { - color: #666; + color: $gl-gray; font-weight: normal; margin-right: 4px; } } -.issuable-affix .context { - font-size: 13px; - - .btn { font-size: 13px; } -} - .project-issuable-filter { .controls { float: right; diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml index b7bca6dae09..507757f6a2b 100644 --- a/app/views/projects/_md_preview.html.haml +++ b/app/views/projects/_md_preview.html.haml @@ -1,6 +1,6 @@ .md-area .md-header.clearfix - %ul.nav.nav-tabs + %ul.center-top-menu %li.active = link_to '#md-write-holder', class: 'js-md-write-button', tabindex: '-1' do Write @@ -14,7 +14,7 @@ You are about to add %strong %span.js-referenced-users-count 0 - people + people to the discussion. Proceed with caution. %div -- cgit v1.2.1 From 1240a7e06586f36ea1094dc87b2d04efaf524896 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 09:32:06 +0200 Subject: Improve font size on issues/mr list Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/issues.scss | 3 +-- app/assets/stylesheets/pages/merge_requests.scss | 1 - app/views/projects/issues/_issue.html.haml | 2 +- app/views/projects/merge_requests/_merge_request.html.haml | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index c407d53118e..1732072b5bf 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -1,6 +1,6 @@ .issues-list { .issue { - padding: 10px 15px; + padding: 10px $gl-padding; position: relative; .issue-title { @@ -11,7 +11,6 @@ .issue-info { color: $gl-gray; - font-size: 13px; } .issue-check { diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index d5ede5349d1..a8db3d401bd 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -128,7 +128,6 @@ .merge-request-info { color: $gl-gray; - font-size: 13px; } } diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index b6910c8f796..55ce912829d 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -41,4 +41,4 @@ = issue.task_status .pull-right.issue-updated-at - %small updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')} + %span updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')} diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 4295c828dad..25e4e8ba80d 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -43,4 +43,4 @@ = merge_request.task_status .pull-right.hidden-xs - %small updated #{time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago')} + %span updated #{time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago')} -- cgit v1.2.1 From def4d8b90617dae50f3fa23e67b2ee383f84f82e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 09:58:43 +0200 Subject: Improve issue/mr title and description styles Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/issuable.scss | 12 ++++++++++++ app/assets/stylesheets/pages/issues.scss | 5 ----- app/assets/stylesheets/pages/notes.scss | 5 ++--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index e13c8f9eb98..b5c61f7f91d 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -66,4 +66,16 @@ color: $gl-text-color; } } + + .issue-title { + margin: 0; + } + + .description { + margin-top: 6px; + + p:last-child { + margin-bottom: 0; + } + } } diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 1732072b5bf..4bf58cb4a59 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -132,11 +132,6 @@ form.edit-issue { } } -h2.issue-title { - margin-top: 0; - font-weight: bold; -} - .issue-form .select2-container { width: 250px !important; } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 85c828ec1ad..77a112f8c77 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -59,7 +59,7 @@ ul.notes { margin-top: 1px; border: 1px solid #bbb; background-color: transparent; - color: #999; + color: $gl-gray; } } @@ -176,8 +176,7 @@ ul.notes { a { margin-left: 5px; - - color: #999; + color: $gl-gray; i.fa { font-size: 16px; -- cgit v1.2.1 From 4bea030c88d1462be70a67b72505cb093868ec29 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 10:12:14 +0200 Subject: Style system notes Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/base/gl_variables.scss | 7 ++++++ app/assets/stylesheets/generic/timeline.scss | 36 +++------------------------ app/assets/stylesheets/pages/notes.scss | 9 +++---- app/views/projects/notes/_note.html.haml | 11 ++------ 4 files changed, 16 insertions(+), 47 deletions(-) diff --git a/app/assets/stylesheets/base/gl_variables.scss b/app/assets/stylesheets/base/gl_variables.scss index 2447ee21898..d18b48eaca9 100644 --- a/app/assets/stylesheets/base/gl_variables.scss +++ b/app/assets/stylesheets/base/gl_variables.scss @@ -148,3 +148,10 @@ $btn-default-border: #e7e9ed; // //## $nav-link-padding: 13px $gl-padding; + +//== Code +// +//## +$pre-bg: #f8fafc !default; +$pre-color: $gl-gray !default; +$pre-border-color: #e7e9ed; diff --git a/app/assets/stylesheets/generic/timeline.scss b/app/assets/stylesheets/generic/timeline.scss index 54dc4c52418..668a6f848cc 100644 --- a/app/assets/stylesheets/generic/timeline.scss +++ b/app/assets/stylesheets/generic/timeline.scss @@ -28,39 +28,9 @@ } } - .system-note .timeline-entry-inner { - .timeline-icon { - float: left; - margin-left: 12px; - margin-top: 8px; - @include box-shadow(none); - - span { - margin: 0 2px; - font-size: 16px; - color: #eeeeee; - } - } - - .timeline-content { - background: none; - margin-left: 45px; - padding: 0px 15px; - - &:after { border: 0; } - - .note-header { - span { font-size: 12px; } - - .avatar { - margin-right: 5px; - } - } - - .note-text { - font-size: 12px; - margin-left: 20px; - } + .system-note { + .note-text { + color: $gl-gray !important; } } } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 77a112f8c77..9603624a657 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -34,10 +34,8 @@ ul.notes { content: "\00b7"; } - font-size: 13px; - a { - @extend .cgray; + color: $gl-gray; &:hover { text-decoration: underline; @@ -45,8 +43,9 @@ ul.notes { } } .author { - color: #333; - font-weight: bold; + color: #4c4e54; + margin-right: 3px; + &:hover { color: $gl-link-color; } diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index de75d44fc41..9bfbde02ca2 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -1,11 +1,8 @@ %li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: { discussion: note.discussion_id } } .timeline-entry-inner .timeline-icon - - if note.system - %span= icon('circle') - - else - = link_to user_path(note.author) do - = image_tag avatar_icon(note.author_email), class: 'avatar s40', alt: '' + = link_to user_path(note.author) do + = image_tag avatar_icon(note.author_email), class: 'avatar s40', alt: '' .timeline-content .note-header - if note_editable?(note) @@ -22,10 +19,6 @@ %span.note-role.label = member.human_access - - if note.system - = link_to user_path(note.author) do - = image_tag avatar_icon(note.author_email), class: 'avatar s16', alt: '' - = link_to_member(note.project, note.author, avatar: false) %span.author-username -- cgit v1.2.1 From 0250bab8e928a18faf09c4668ba2fcbbfa64da48 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 10:23:09 +0200 Subject: Style wiki pages Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/wikis/_main_links.html.haml | 7 +++++++ app/views/projects/wikis/_nav.html.haml | 11 +---------- app/views/projects/wikis/git_access.html.haml | 17 +++++++++-------- app/views/projects/wikis/history.html.haml | 7 ++++--- app/views/projects/wikis/pages.html.haml | 7 ++++--- app/views/projects/wikis/show.html.haml | 19 ++++++++++--------- 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml index acc2c8b2f7f..14f25822259 100644 --- a/app/views/projects/wikis/_main_links.html.haml +++ b/app/views/projects/wikis/_main_links.html.haml @@ -1,4 +1,9 @@ %span.pull-right + - if can?(current_user, :create_wiki, @project) + = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new btn-grouped", "data-toggle" => "modal" do + %i.fa.fa-plus + New Page + - if (@page && @page.persisted?) = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn btn-grouped" do Page History @@ -6,3 +11,5 @@ = link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn btn-grouped" do %i.fa.fa-pencil-square-o Edit + += render 'projects/wikis/new' diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml index ec87c3c765a..fffb4eb31ab 100644 --- a/app/views/projects/wikis/_nav.html.haml +++ b/app/views/projects/wikis/_nav.html.haml @@ -1,4 +1,4 @@ -%ul.nav.nav-tabs +%ul.center-top-menu = nav_link(html_options: {class: params[:id] == 'home' ? 'active' : '' }) do = link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home) @@ -7,13 +7,4 @@ = nav_link(path: 'wikis#git_access') do = link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do - %i.fa.fa-download Git Access - - - if can?(current_user, :create_wiki, @project) - .pull-right - = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do - %i.fa.fa-plus - New Page - -= render 'projects/wikis/new' diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index 825f2a161c4..62071e29d74 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -1,15 +1,16 @@ - page_title "Git Access", "Wiki" = render 'nav' -.row - .col-sm-6 - %h3.page-title - Git access for - %strong= @project_wiki.path_with_namespace +.gray-content-block + .row + .col-sm-6 + %h3.page-title + Git access for + %strong= @project_wiki.path_with_namespace - .col-sm-6 - = render "shared/clone_panel", project: @project_wiki + .col-sm-6 + = render "shared/clone_panel", project: @project_wiki -.git-empty +.git-empty.prepend-top-default %fieldset %legend Install Gollum: %pre.dark diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml index 673ec2d20e5..7c81ad53d32 100644 --- a/app/views/projects/wikis/history.html.haml +++ b/app/views/projects/wikis/history.html.haml @@ -1,8 +1,9 @@ - page_title "History", @page.title, "Wiki" = render 'nav' -%h3.page-title - %span.light History for - = link_to @page.title, namespace_project_wiki_path(@project.namespace, @project, @page) +.gray-content-block + %h3.page-title + %span.light History for + = link_to @page.title, namespace_project_wiki_path(@project.namespace, @project, @page) %table.table %thead diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 890ff1aed73..7fb91507eb2 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -1,8 +1,9 @@ - page_title "All Pages", "Wiki" = render 'nav' -%h3.page-title - All Pages -%ul.bordered-list +.gray-content-block + %h3.page-title + All Pages +%ul.content-list - @wiki_pages.each do |wiki_page| %li %h4 diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 90c4b83cf37..126810811ec 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -1,25 +1,26 @@ - page_title @page.title, "Wiki" = render 'nav' -%h3.page-title - = @page.title + +.gray-content-block = render 'main_links' + %h3.page-title + = @page.title.capitalize -.wiki-last-edit-by - Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} + .wiki-last-edit-by + Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} - if @page.historical? .warning_message This is an old version of this page. You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", namespace_project_wiki_history_path(@project.namespace, @project, @page)}. -%hr -.wiki-holder +.wiki-holder.prepend-top-default .wiki = preserve do = render_wiki_content(@page) -%hr -.wiki-last-edit-by - Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} +.gray-content-block.footer-block + .wiki-last-edit-by + Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} -- cgit v1.2.1 From 1e1376f230c98d4610eb77131b0b67b2296abecc Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 11:14:48 +0200 Subject: Style milestones Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/base/gl_bootstrap.scss | 6 ++-- app/assets/stylesheets/pages/milestone.scss | 4 +++ .../dashboard/milestones/_milestone.html.haml | 24 +++++++------ app/views/groups/milestones/_milestone.html.haml | 36 ++++++++++--------- app/views/projects/milestones/_milestone.html.haml | 42 ++++++++++++---------- 5 files changed, 64 insertions(+), 48 deletions(-) diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index 21acbfa5e5a..ae72c5b8d97 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -85,14 +85,14 @@ // Labels .label { padding: 2px 4px; - font-size: 12px; + font-size: 13px; font-style: normal; font-weight: normal; display: inline-block; &.label-gray { - background-color: #eee; - color: #999; + background-color: #f8fafc; + color: $gl-gray; text-shadow: none; } diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss index 15e3948e402..e80dc9e84a1 100644 --- a/app/assets/stylesheets/pages/milestone.scss +++ b/app/assets/stylesheets/pages/milestone.scss @@ -6,4 +6,8 @@ li.milestone { h4 { font-weight: bold; } + + .progress { + height: 6px; + } } diff --git a/app/views/dashboard/milestones/_milestone.html.haml b/app/views/dashboard/milestones/_milestone.html.haml index d6f3e029a38..55080d6b3fe 100644 --- a/app/views/dashboard/milestones/_milestone.html.haml +++ b/app/views/dashboard/milestones/_milestone.html.haml @@ -1,20 +1,22 @@ %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } - %h4 - = link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title) + .row + .col-sm-6 + %strong + = link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title) + .col-sm-6 + .pull-right.light #{milestone.percent_complete}% complete .row .col-sm-6 = link_to issues_dashboard_path(milestone_title: milestone.title) do = pluralize milestone.issue_count, 'Issue' -   + · = link_to merge_requests_dashboard_path(milestone_title: milestone.title) do = pluralize milestone.merge_requests_count, 'Merge Request' -   - %span.light #{milestone.percent_complete}% complete - .col-sm-6 = milestone_progress_bar(milestone) - %div - - milestone.milestones.each do |milestone| - = link_to milestone_path(milestone) do - %span.label.label-gray - = milestone.project.name_with_namespace + .row + .col-sm-6 + - milestone.milestones.each do |milestone| + = link_to milestone_path(milestone) do + %span.label.label-gray + = milestone.project.name_with_namespace diff --git a/app/views/groups/milestones/_milestone.html.haml b/app/views/groups/milestones/_milestone.html.haml index ba30e6e07c6..41dffdd2fb8 100644 --- a/app/views/groups/milestones/_milestone.html.haml +++ b/app/views/groups/milestones/_milestone.html.haml @@ -1,25 +1,29 @@ %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } - .pull-right - - if can?(current_user, :admin_group, @group) - - if milestone.closed? - = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen" - - else - = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close" - %h4 - = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title) + .row + .col-sm-6 + %strong + = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title) + .col-sm-6 + .pull-right.light #{milestone.percent_complete}% complete .row .col-sm-6 = link_to issues_group_path(@group, milestone_title: milestone.title) do = pluralize milestone.issue_count, 'Issue' -   + · = link_to merge_requests_group_path(@group, milestone_title: milestone.title) do = pluralize milestone.merge_requests_count, 'Merge Request' -   - %span.light #{milestone.percent_complete}% complete .col-sm-6 = milestone_progress_bar(milestone) - %div - - milestone.milestones.each do |milestone| - = link_to milestone_path(milestone) do - %span.label.label-gray - = milestone.project.name + .row + .col-sm-6 + %div + - milestone.milestones.each do |milestone| + = link_to milestone_path(milestone) do + %span.label.label-gray + = milestone.project.name + .col-sm-6 + - if can?(current_user, :admin_group, @group) + - if milestone.closed? + = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-xs btn-grouped btn-reopen" + - else + = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-xs btn-close" diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml index 2ce5358fa74..5e93d55b1fb 100644 --- a/app/views/projects/milestones/_milestone.html.haml +++ b/app/views/projects/milestones/_milestone.html.haml @@ -1,28 +1,34 @@ %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } - .pull-right - - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? - = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-sm edit-milestone-link btn-grouped" do - %i.fa.fa-pencil-square-o - Edit - = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close" - = link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-sm btn-remove" do - %i.fa.fa-trash-o - Remove + .row + .col-sm-6 + %strong + = link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - %h4 - = link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - - if milestone.expired? and not milestone.closed? - %span.cred (Expired) - %small - = milestone.expires_at + .col-sm-6 + .pull-right.light #{milestone.percent_complete}% complete .row .col-sm-6 = link_to namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do = pluralize milestone.issues.count, 'Issue' -   + · = link_to namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do = pluralize milestone.merge_requests.count, 'Merge Request' -   - %span.light #{milestone.percent_complete}% complete .col-sm-6 = milestone_progress_bar(milestone) + + .row + .col-sm-6 + - if milestone.expired? and not milestone.closed? + %span.cred (Expired) + - if milestone.expires_at + %span + = milestone.expires_at + .col-sm-6 + - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? + = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs edit-milestone-link btn-grouped" do + %i.fa.fa-pencil-square-o + Edit + = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close" + = link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove" do + %i.fa.fa-trash-o + Remove -- cgit v1.2.1 From 925d3926820b019c72bf29b2cf6cb6af2a28d91f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 11:21:33 +0200 Subject: Make comment form bigger Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/generic/markdown_area.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/generic/markdown_area.scss b/app/assets/stylesheets/generic/markdown_area.scss index 2dcff516e83..ed0333d2336 100644 --- a/app/assets/stylesheets/generic/markdown_area.scss +++ b/app/assets/stylesheets/generic/markdown_area.scss @@ -83,7 +83,7 @@ .md-preview-holder { background: #FFF; border: 1px solid #ddd; - min-height: 100px; + min-height: 169px; padding: 5px; box-shadow: none; } @@ -108,7 +108,7 @@ .markdown-area { background: #FFF; border: 1px solid #ddd; - min-height: 100px; + min-height: 140px; padding: 5px; box-shadow: none; width: 100%; -- cgit v1.2.1 From 9f31f95adad5500045ef35b57d133c633cd08524 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Sep 2015 11:18:55 +0100 Subject: Escape user-provided content in preserved HAML sections --- app/views/projects/empty.html.haml | 6 +++--- .../projects/merge_requests/show/_how_to_merge.html.haml | 16 ++++++++-------- app/views/projects/wikis/git_access.html.haml | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index e577d35d560..798f1c47da5 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -22,15 +22,15 @@ %h5 Git global setup %pre.light-well :preserve - git config --global user.name "#{git_user_name}" - git config --global user.email "#{git_user_email}" + git config --global user.name "#{h git_user_name}" + git config --global user.email "#{h git_user_email}" %fieldset %h5 Create a new repository %pre.light-well :preserve git clone #{ content_tag(:span, default_url_to_repo, class: 'clone')} - cd #{@project.path} + cd #{h @project.path} touch README.md git add README.md git commit -m "add README" diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml index db1575f899a..f18cf96c17d 100644 --- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml +++ b/app/views/projects/merge_requests/show/_how_to_merge.html.haml @@ -11,12 +11,12 @@ %pre.dark - if @merge_request.for_fork? :preserve - git fetch #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch} - git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} FETCH_HEAD + git fetch #{h @merge_request.source_project.http_url_to_repo} #{h @merge_request.source_branch} + git checkout -b #{h @merge_request.source_project_path}-#{h @merge_request.source_branch} FETCH_HEAD - else :preserve git fetch origin - git checkout -b #{@merge_request.source_branch} origin/#{@merge_request.source_branch} + git checkout -b #{h @merge_request.source_branch} origin/#{h @merge_request.source_branch} %p %strong Step 2. Review the changes locally @@ -27,18 +27,18 @@ %pre.dark - if @merge_request.for_fork? :preserve - git checkout #{@merge_request.target_branch} - git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch} + git checkout #{h @merge_request.target_branch} + git merge --no-ff #{h @merge_request.source_project_path}-#{h @merge_request.source_branch} - else :preserve - git checkout #{@merge_request.target_branch} - git merge --no-ff #{@merge_request.source_branch} + git checkout #{h @merge_request.target_branch} + git merge --no-ff #{h @merge_request.source_branch} %p %strong Step 4. Push the result of the merge to GitLab %pre.dark :preserve - git push origin #{@merge_request.target_branch} + git push origin #{h @merge_request.target_branch} - unless @merge_request.can_be_merged_by?(current_user) %p Note that pushing to GitLab requires write access to this repository. diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index 825f2a161c4..fd266baf660 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -20,7 +20,7 @@ %pre.dark :preserve git clone #{ content_tag(:span, default_url_to_repo(@project_wiki), class: 'clone')} - cd #{@project_wiki.path} + cd #{h @project_wiki.path} %legend Start Gollum And Edit Locally: %pre.dark -- cgit v1.2.1 From 7fe6d11a3d29884db70729c46a2f8fcd19955a65 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 15:02:51 +0200 Subject: Move group member title to header Signed-off-by: Dmitriy Zaporozhets --- app/views/groups/group_members/index.html.haml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml index dba395cc8fa..3a6d07ebddf 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -1,15 +1,13 @@ - page_title "Members" +- header_title group_title(@group, "Members", group_group_members_path(@group)) - show_roles = should_user_see_group_roles?(current_user, @group) -%h3.page-title - Group members - if show_roles %p.light Members of group have access to all group projects. Read more about permissions %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" -%hr .clearfix.js-toggle-container = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do -- cgit v1.2.1 From 2fde90a2c23c7bdb7daffd9b15e3b416fb15d33f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 15:35:25 +0200 Subject: Fix small font size for diff comments Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/diff.scss | 4 ++-- app/assets/stylesheets/pages/notes.scss | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 1557c243db5..f816d32a93c 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -45,7 +45,7 @@ overflow-y: hidden; background: #FFF; color: #333; - font-size: $code_font_size; + .old { span.idiff { background-color: #f8cbcb; @@ -82,7 +82,7 @@ border: none; margin: 0px; padding: 0px; - td { + .line_holder td { line-height: $code_line_height; font-size: $code_font_size; } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 9603624a657..bd9e91a3510 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -132,8 +132,6 @@ ul.notes { } .diff-file .notes_holder { - font-size: 13px; - line-height: 18px; font-family: $regular_font; td { -- cgit v1.2.1 From 70aecc34cfbdc9dbb10439c4c92679c00f767e2d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 15:40:14 +0200 Subject: Improve commit page style Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/commit.scss | 5 ----- app/views/projects/commit/_commit_box.html.haml | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss index 5436c6dad97..f9e9b024d47 100644 --- a/app/assets/stylesheets/pages/commit.scss +++ b/app/assets/stylesheets/pages/commit.scss @@ -47,11 +47,6 @@ } .commit-box { - margin: 10px 0; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - padding: 20px 0; - .commit-title { margin: 0; } diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 3f645b81397..2ac79e87b4a 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -41,7 +41,7 @@ .commit-info-row.branches %i.fa.fa-spinner.fa-spin -.commit-box +.commit-box.gray-content-block.middle-block %h3.commit-title = gfm escape_once(@commit.title) - if @commit.description.present? -- cgit v1.2.1 From 46511558815306cf76b0c83637bee018f3caa926 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 16:11:41 +0200 Subject: Make system note different from regular comments Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/notes.scss | 13 +++++++++++++ app/views/projects/notes/_discussion.html.haml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index bd9e91a3510..2544356a5f6 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -14,6 +14,19 @@ ul.notes { margin: 0px; padding: 0px; + .system-note { + font-size: 14px; + padding-top: 10px; + padding-bottom: 10px; + background: #f8fafc; + + .timeline-icon { + .avatar { + visibility: hidden; + } + } + } + .discussion-header, .note-header { @extend .cgray; diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml index b8068835b3a..6daf2d15d07 100644 --- a/app/views/projects/notes/_discussion.html.haml +++ b/app/views/projects/notes/_discussion.html.haml @@ -1,5 +1,5 @@ - note = discussion_notes.first -.timeline-entry +.timeline-entry.prepend-top-default .timeline-entry-inner .timeline-icon = link_to user_path(note.author) do -- cgit v1.2.1 From e9cf79da2f90a33d1058a1735d8a71a38df8f442 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 16:42:18 +0200 Subject: Style merge request page Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/merge_requests.scss | 25 ++++++++++++++++------ app/views/projects/merge_requests/_show.html.haml | 3 --- .../merge_requests/widget/open/_accept.html.haml | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index a8db3d401bd..d8c8e5ad0a4 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -3,10 +3,10 @@ * */ .mr-state-widget { - background: #FAFAFA; + background: #f8fafc; margin-bottom: 20px; - color: #666; - border: 1px solid #e5e5e5; + color: $gl-gray; + border: 1px solid #eef0f2; @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05)); @include border-radius(3px); @@ -29,6 +29,14 @@ padding: 5px; line-height: 20px; + &.right { + float: right; + padding-top: 12px; + a { + color: $gl-gray; + } + } + .remove_source_checkbox { margin: 0; } @@ -36,7 +44,7 @@ } .ci_widget { - border-bottom: 1px solid #EEE; + border-bottom: 1px solid #eef0f2; i { margin-right: 4px; @@ -91,9 +99,12 @@ .merge-request .merge-request-tabs{ @include nav-menu; - margin-bottom: -15px; - margin-top: 26px; - text-align: left; + margin: -$gl-padding; + padding: $gl-padding; + text-align: center; + border-top: 1px solid #e7e9ed; + margin-top: 18px; + margin-bottom: 3px; } .mr_source_commit, diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 721993fb279..61e04dce5ab 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -40,17 +40,14 @@ %ul.merge-request-tabs %li.notes-tab = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#notes', action: 'notes', toggle: 'tab'} do - = icon('comments') Discussion %span.badge= @merge_request.mr_and_commit_notes.user.count %li.commits-tab = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#commits', action: 'commits', toggle: 'tab'} do - = icon('history') Commits %span.badge= @commits.size %li.diffs-tab = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do - = icon('list-alt') Changes %span.badge= @merge_request.diffs.size diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index b61e193fc42..613525437ab 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -9,7 +9,7 @@ = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do = check_box_tag :should_remove_source_branch Remove source branch - .accept-control + .accept-control.right = link_to "#", class: "modify-merge-commit-link js-toggle-button" do = icon('edit') Modify commit message -- cgit v1.2.1 From 86556a079e34eb1267e63f7b39cc018665e21bfc Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 8 Sep 2015 17:22:26 +0200 Subject: Improve diff UI and mr compare page Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/commit.scss | 8 -------- app/assets/stylesheets/pages/diff.scss | 10 ++++++++-- app/views/projects/diffs/_diffs.html.haml | 4 ++-- app/views/projects/diffs/_stats.html.haml | 2 +- app/views/projects/merge_requests/_new_compare.html.haml | 2 +- app/views/projects/merge_requests/_new_submit.html.haml | 4 +--- 6 files changed, 13 insertions(+), 17 deletions(-) diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss index f9e9b024d47..051ca3792c3 100644 --- a/app/assets/stylesheets/pages/commit.scss +++ b/app/assets/stylesheets/pages/commit.scss @@ -26,14 +26,6 @@ margin-top: 10px; } -.commit-stat-summary { - color: #666; - font-size: 14px; - font-weight: normal; - padding: 3px 0; - margin-bottom: 10px; -} - .commit-info-row { margin-bottom: 10px; .avatar { diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index f816d32a93c..487b600e31d 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -1,6 +1,8 @@ .diff-file { - border: 1px solid $border-color; - margin-bottom: 1em; + margin-left: -16px; + margin-right: -16px; + border: none; + border-bottom: 1px solid #E7E9EE; .diff-header { position: relative; @@ -367,3 +369,7 @@ white-space: pre-wrap; } +.inline-parallel-buttons { + float: right; + margin-top: -5px; +} diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml index 30943f49bba..2f24dc7c909 100644 --- a/app/views/projects/diffs/_diffs.html.haml +++ b/app/views/projects/diffs/_diffs.html.haml @@ -1,8 +1,8 @@ - if params[:view] == 'parallel' - fluid_layout true -.prepend-top-20.append-bottom-20 - .pull-right +.gray-content-block.second-block + .inline-parallel-buttons .btn-group = inline_diff_btn = parallel_diff_btn diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml index 1625930615a..c4d7f26430b 100644 --- a/app/views/projects/diffs/_stats.html.haml +++ b/app/views/projects/diffs/_stats.html.haml @@ -10,7 +10,7 @@ and %strong.cred #{@commit.stats.deletions} deletions .file-stats.js-toggle-content.hide - %ul.bordered-list + %ul - diffs.each_with_index do |diff, i| %li - if diff.deleted_file diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml index 7709330611a..452006162db 100644 --- a/app/views/projects/merge_requests/_new_compare.html.haml +++ b/app/views/projects/merge_requests/_new_compare.html.haml @@ -37,7 +37,7 @@ %h4 Compare failed %p We can't compare selected branches. It may be because of huge diff. Please try again or select different branches. - else - .light-well + .light-well.append-bottom-10 .center %h4 There isn't anything to merge. diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 76f44211dac..46aeecd8733 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -18,15 +18,13 @@ = f.hidden_field :target_branch .mr-compare.merge-request - %ul.nav.nav-tabs.merge-request-tabs + %ul.merge-request-tabs %li.commits-tab = link_to url_for(params), data: {target: '#commits', action: 'commits', toggle: 'tab'} do - = icon('history') Commits %span.badge= @commits.size %li.diffs-tab.active = link_to url_for(params), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do - = icon('list-alt') Changes %span.badge= @diffs.size -- cgit v1.2.1 From 983a102bd028bf7a6335b6674059eb004d4171f3 Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Tue, 8 Sep 2015 12:28:28 -0500 Subject: Added meta tag for referrer, so that only the origin is sent to third party sites, instead of the entire URL, thus avoiding the leak of sensitive information like password reset tokens. --- app/views/layouts/_head.html.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 397649dacf8..c3b137e3ddf 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -3,6 +3,7 @@ %meta{charset: "utf-8"} %meta{'http-equiv' => 'X-UA-Compatible', content: 'IE=edge'} %meta{content: "GitLab Community Edition", name: "description"} + %meta{name: 'referrer', content: 'origin'} %title= page_title -- cgit v1.2.1 From 4d6f8a6aee345d12d81f03f8dc1dfdfc2e3bd777 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 8 Sep 2015 13:31:54 -0400 Subject: Bump gitlab-shell to v2.6.5 --- GITLAB_SHELL_VERSION | 2 +- doc/install/installation.md | 2 +- doc/update/6.x-or-7.x-to-7.14.md | 4 ++-- doc/update/7.13-to-7.14.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 2714f5313ae..57cf282ebbc 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -2.6.4 +2.6.5 diff --git a/doc/install/installation.md b/doc/install/installation.md index 52031e9b9a1..ee13b0f2537 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -299,7 +299,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da GitLab Shell is an SSH access and repository management software developed specially for GitLab. # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed): - sudo -u git -H bundle exec rake gitlab:shell:install[v2.6.3] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production + sudo -u git -H bundle exec rake gitlab:shell:install[v2.6.5] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production # By default, the gitlab-shell config is generated from your main GitLab config. # You can review (and modify) the gitlab-shell config as follows: diff --git a/doc/update/6.x-or-7.x-to-7.14.md b/doc/update/6.x-or-7.x-to-7.14.md index a1488474f60..5bc1f84270a 100644 --- a/doc/update/6.x-or-7.x-to-7.14.md +++ b/doc/update/6.x-or-7.x-to-7.14.md @@ -127,7 +127,7 @@ sudo apt-get install nodejs ```bash cd /home/git/gitlab-shell sudo -u git -H git fetch -sudo -u git -H git checkout v2.6.4 +sudo -u git -H git checkout v2.6.5 ``` ## 7. Install libs, migrations, etc. @@ -167,7 +167,7 @@ git diff 6-0-stable:config/gitlab.yml.example 7.14-stable:config/gitlab.yml.exam * Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/gitlab.yml.example but with your settings. * Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/unicorn.rb.example but with your settings. -* Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.6.0/config.yml.example but with your settings. +* Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.6.5/config.yml.example but with your settings. * Copy rack attack middleware config ```bash diff --git a/doc/update/7.13-to-7.14.md b/doc/update/7.13-to-7.14.md index 7c2d3f4498a..6dd9727fb49 100644 --- a/doc/update/7.13-to-7.14.md +++ b/doc/update/7.13-to-7.14.md @@ -63,7 +63,7 @@ sudo -u git -H git checkout 7-14-stable-ee ```bash cd /home/git/gitlab-shell sudo -u git -H git fetch -sudo -u git -H git checkout v2.6.4 +sudo -u git -H git checkout v2.6.5 ``` ### 5. Install libs, migrations, etc. -- cgit v1.2.1 From e156f42079ebf8247b6a39fa6314d4d5c6b73d12 Mon Sep 17 00:00:00 2001 From: Jared Szechy Date: Tue, 4 Aug 2015 18:21:12 -0400 Subject: FogBugz project import --- CHANGELOG | 1 + Gemfile | 4 + Gemfile.lock | 6 + app/controllers/application_controller.rb | 7 +- app/controllers/import/fogbugz_controller.rb | 106 ++++++++ app/models/application_setting.rb | 2 +- app/models/project.rb | 2 + app/services/projects/download_service.rb | 43 +++ app/views/import/fogbugz/new.html.haml | 25 ++ app/views/import/fogbugz/new_user_map.html.haml | 49 ++++ app/views/import/fogbugz/status.html.haml | 51 ++++ app/views/projects/new.html.haml | 5 + app/workers/repository_import_worker.rb | 35 ++- config/initializers/1_settings.rb | 2 +- config/routes.rb | 9 + doc/workflow/importing/README.md | 1 + .../fogbugz_importer/fogbugz_import_finished.png | Bin 0 -> 53276 bytes .../fogbugz_importer/fogbugz_import_login.png | Bin 0 -> 44444 bytes .../fogbugz_import_select_fogbogz.png | Bin 0 -> 35415 bytes .../fogbugz_import_select_project.png | Bin 0 -> 62552 bytes .../fogbugz_importer/fogbugz_import_user_map.png | Bin 0 -> 157856 bytes .../importing/import_projects_from_fogbugz.md | 29 ++ lib/gitlab/fogbugz_import/client.rb | 56 ++++ lib/gitlab/fogbugz_import/importer.rb | 298 +++++++++++++++++++++ lib/gitlab/fogbugz_import/project_creator.rb | 38 +++ lib/gitlab/fogbugz_import/repository.rb | 31 +++ lib/gitlab/import_sources.rb | 1 + spec/controllers/import/fogbugz_controller_spec.rb | 39 +++ spec/services/projects/download_service_spec.rb | 65 +++++ 29 files changed, 889 insertions(+), 16 deletions(-) create mode 100644 app/controllers/import/fogbugz_controller.rb create mode 100644 app/services/projects/download_service.rb create mode 100644 app/views/import/fogbugz/new.html.haml create mode 100644 app/views/import/fogbugz/new_user_map.html.haml create mode 100644 app/views/import/fogbugz/status.html.haml create mode 100644 doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png create mode 100644 doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png create mode 100644 doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png create mode 100644 doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png create mode 100644 doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png create mode 100644 doc/workflow/importing/import_projects_from_fogbugz.md create mode 100644 lib/gitlab/fogbugz_import/client.rb create mode 100644 lib/gitlab/fogbugz_import/importer.rb create mode 100644 lib/gitlab/fogbugz_import/project_creator.rb create mode 100644 lib/gitlab/fogbugz_import/repository.rb create mode 100644 spec/controllers/import/fogbugz_controller_spec.rb create mode 100644 spec/services/projects/download_service_spec.rb diff --git a/CHANGELOG b/CHANGELOG index 247eb1e3643..dd48bab978c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -47,6 +47,7 @@ v 7.14.1 - Only include base URL in OmniAuth full_host parameter (Stan Hu) - Fix Error 500 in API when accessing a group that has an avatar (Stan Hu) - Ability to enable SSL verification for Webhooks + - Add FogBugz project import (Jared Szechy) v 7.14.0 - Fix bug where non-project members of the target project could set labels on new merge requests. diff --git a/Gemfile b/Gemfile index cca8fc38e57..d609ff6610f 100644 --- a/Gemfile +++ b/Gemfile @@ -157,6 +157,9 @@ gem "slack-notifier", "~> 1.0.0" # Asana integration gem 'asana', '~> 0.0.6' +# FogBugz integration +gem 'ruby-fogbugz' + # d3 gem 'd3_rails', '~> 3.5.5' @@ -259,6 +262,7 @@ group :test do gem 'email_spec', '~> 1.6.0' gem 'webmock', '~> 1.21.0' gem 'test_after_commit' + gem 'sham_rack' end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index 2df318f3382..dce7e4964a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -575,6 +575,8 @@ GEM powerpack (~> 0.0.6) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.4) + ruby-fogbugz (0.1.1) + crack ruby-progressbar (1.7.1) ruby-saml (1.0.0) nokogiri (>= 1.5.10) @@ -609,6 +611,8 @@ GEM thor (~> 0.14) settingslogic (2.0.9) sexp_processor (4.4.5) + sham_rack (1.3.6) + rack shoulda-matchers (2.8.0) activesupport (>= 3.0.0) sidekiq (3.3.0) @@ -845,12 +849,14 @@ DEPENDENCIES rqrcode-rails3 rspec-rails (~> 3.3.0) rubocop (= 0.28.0) + ruby-fogbugz sanitize (~> 2.0) sass-rails (~> 4.0.5) sdoc seed-fu select2-rails (~> 3.5.9) settingslogic + sham_rack shoulda-matchers (~> 2.8.0) sidekiq (~> 3.3) sidetiq (= 0.6.3) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cb1cf13d34d..4c112534ae6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,5 @@ require 'gon' +require 'fogbugz' class ApplicationController < ActionController::Base include Gitlab::CurrentSettings @@ -20,7 +21,7 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception helper_method :abilities, :can?, :current_application_settings - helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :git_import_enabled? + helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled? rescue_from Encoding::CompatibilityError do |exception| log_exception(exception) @@ -337,6 +338,10 @@ class ApplicationController < ActionController::Base current_application_settings.import_sources.include?('google_code') end + def fogbugz_import_enabled? + current_application_settings.import_sources.include?('fogbugz') + end + def git_import_enabled? current_application_settings.import_sources.include?('git') end diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb new file mode 100644 index 00000000000..bda534fb4de --- /dev/null +++ b/app/controllers/import/fogbugz_controller.rb @@ -0,0 +1,106 @@ +class Import::FogbugzController < Import::BaseController + before_action :verify_fogbugz_import_enabled + before_action :user_map, only: [:new_user_map, :create_user_map] + + # Doesn't work yet due to bug in ruby-fogbugz, see below + rescue_from Fogbugz::AuthenticationException, with: :fogbugz_unauthorized + + def new + + end + + def callback + begin + res = Gitlab::FogbugzImport::Client.new(import_params.symbolize_keys) + rescue + # Needed until https://github.com/firmafon/ruby-fogbugz/pull/9 is merged + return redirect_to :back, alert: 'Could not authenticate with FogBugz, check your URL, email, and password' + end + session[:fogbugz_token] = res.get_token + session[:fogbugz_uri] = params[:uri] + + redirect_to new_user_map_import_fogbugz_path + end + + def new_user_map + + end + + def create_user_map + user_map = params[:users] + + unless user_map.is_a?(Hash) && user_map.all? { |k, v| !v[:name].blank? } + flash.now[:alert] = 'All users must have a name.' + + render 'new_user_map' and return + end + + session[:fogbugz_user_map] = user_map + + flash[:notice] = 'The user map has been saved. Continue by selecting the projects you want to import.' + + redirect_to status_import_fogbugz_path + end + + def status + unless client.valid? + return redirect_to new_import_fogbugz_path + end + + @repos = client.repos + + @already_added_projects = current_user.created_projects.where(import_type: 'fogbugz') + already_added_projects_names = @already_added_projects.pluck(:import_source) + + @repos.reject! { |repo| already_added_projects_names.include? repo.name } + end + + def jobs + jobs = current_user.created_projects.where(import_type: 'fogbugz').to_json(only: [:id, :import_status]) + render json: jobs + end + + def create + @repo_id = params[:repo_id] + repo = client.repo(@repo_id) + fb_session = { uri: session[:fogbugz_uri], token: session[:fogbugz_token] } + @target_namespace = current_user.namespace + @project_name = repo.name + + namespace = @target_namespace + + umap = session[:fogbugz_user_map] || client.user_map + + @project = Gitlab::FogbugzImport::ProjectCreator.new(repo, fb_session, namespace, current_user, umap).execute + end + + private + + def client + @client ||= Gitlab::FogbugzImport::Client.new(token: session[:fogbugz_token], uri: session[:fogbugz_uri]) + end + + def user_map + @user_map ||= begin + user_map = client.user_map + + stored_user_map = session[:fogbugz_user_map] + user_map.update(stored_user_map) if stored_user_map + + user_map + end + end + + def fogbugz_unauthorized(exception) + flash[:alert] = exception.message + redirect_to new_import_fogbugz_path + end + + def import_params + params.permit(:uri, :email, :password) + end + + def verify_fogbugz_import_enabled + not_found! unless fogbugz_import_enabled? + end +end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 8f27e35d723..c8841178e93 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -83,7 +83,7 @@ class ApplicationSetting < ActiveRecord::Base default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], restricted_signup_domains: Settings.gitlab['restricted_signup_domains'], - import_sources: ['github','bitbucket','gitlab','gitorious','google_code','git'] + import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'] ) end diff --git a/app/models/project.rb b/app/models/project.rb index 8e33a4b2f0f..c2d7fa5fcb8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -43,6 +43,8 @@ class Project < ActiveRecord::Base extend Gitlab::ConfigHelper extend Enumerize + UNKNOWN_IMPORT_URL = 'http://unknown.git' + default_value_for :archived, false default_value_for :visibility_level, gitlab_config_features.visibility_level default_value_for :issues_enabled, gitlab_config_features.issues diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb new file mode 100644 index 00000000000..99f22293d0d --- /dev/null +++ b/app/services/projects/download_service.rb @@ -0,0 +1,43 @@ +module Projects + class DownloadService < BaseService + + WHITELIST = [ + /^[^.]+\.fogbugz.com$/ + ] + + def initialize(project, url) + @project, @url = project, url + end + + def execute + return nil unless valid_url?(@url) + + uploader = FileUploader.new(@project) + uploader.download!(@url) + uploader.store! + + filename = uploader.image? ? uploader.file.basename : uploader.file.filename + + { + 'alt' => filename, + 'url' => uploader.secure_url, + 'is_image' => uploader.image? + } + end + + private + + def valid_url?(url) + url && http?(url) && valid_domain?(url) + end + + def http?(url) + url =~ /\A#{URI::regexp(['http', 'https'])}\z/ + end + + def valid_domain?(url) + host = URI.parse(url).host + WHITELIST.any? { |entry| entry === host } + end + end +end diff --git a/app/views/import/fogbugz/new.html.haml b/app/views/import/fogbugz/new.html.haml new file mode 100644 index 00000000000..e1bb88ca4ed --- /dev/null +++ b/app/views/import/fogbugz/new.html.haml @@ -0,0 +1,25 @@ +- page_title "FogBugz Import" +%h3.page-title + %i.fa.fa-bug + Import projects from FogBugz +%hr + += form_tag callback_import_fogbugz_path, class: 'form-horizontal' do + %p + To get started you enter your FogBugz URL and login information below. + In the next steps, you'll be able to map users and select the projects + you want to import. + .form-group + = label_tag :uri, 'FogBugz URL', class: 'control-label' + .col-sm-4 + = text_field_tag :uri, nil, placeholder: 'https://mycompany.fogbugz.com', class: 'form-control' + .form-group + = label_tag :email, 'FogBugz Email', class: 'control-label' + .col-sm-4 + = text_field_tag :email, nil, class: 'form-control' + .form-group + = label_tag :password, 'FogBugz Password', class: 'control-label' + .col-sm-4 + = password_field_tag :password, nil, class: 'form-control' + .form-actions + = submit_tag 'Continue to the next step', class: 'btn btn-create' diff --git a/app/views/import/fogbugz/new_user_map.html.haml b/app/views/import/fogbugz/new_user_map.html.haml new file mode 100644 index 00000000000..25cebfb3665 --- /dev/null +++ b/app/views/import/fogbugz/new_user_map.html.haml @@ -0,0 +1,49 @@ +- page_title 'User map', 'FogBugz import' +%h3.page-title + %i.fa.fa-bug + Import projects from FogBugz +%hr + += form_tag create_user_map_import_fogbugz_path, class: 'form-horizontal' do + %p + Customize how FogBugz email addresses and usernames are imported into GitLab. + In the next step, you'll be able to select the projects you want to import. + %p + The user map is a mapping of the FogBugz users that participated on your projects to the way their email address and usernames wil be imported into GitLab. You can change this by populating the table below. + %ul + %li + %strong Default: Map a FogBugz account ID to a full name + %p + An empty GitLab User field will add the FogBugz user's full name + (e.g. "By John Smith") in the description of all issues and comments. + It will also associate and/or assign these issues and comments with + the project creator. + %li + %strong Map a FogBugz account ID to a GitLab user + %p + Selecting a GitLab user will add a link to the GitLab user in the descriptions + of issues and comments (e.g. "By @johnsmith"). It will also + associate and/or assign these issues and comments with the selected user. + + %table.table + %thead + %tr + %th ID + %th Name + %th Email + %th GitLab User + %tbody + - @user_map.each do |id, user| + %tr + %td= id + %td= text_field_tag "users[#{id}][name]", user[:name], class: 'form-control' + %td= text_field_tag "users[#{id}][email]", user[:email], class: 'form-control' + %td + = users_select_tag("users[#{id}][gitlab_user]", class: 'custom-form-control', + scope: :all, email_user: true, selected: user[:gitlab_user]) + + .form-actions + = submit_tag 'Continue to the next step', class: 'btn btn-create' + +:coffeescript + new UsersSelect() diff --git a/app/views/import/fogbugz/status.html.haml b/app/views/import/fogbugz/status.html.haml new file mode 100644 index 00000000000..f179ece402d --- /dev/null +++ b/app/views/import/fogbugz/status.html.haml @@ -0,0 +1,51 @@ +- page_title "FogBugz import" +%h3.page-title + %i.fa.fa-bug + Import projects from FogBugz + +- if @repos.any? + %p.light + Select projects you want to import. + %p.light + Optionally, you can + = link_to 'customize', new_user_map_import_fogbugz_path + how FogBugz email addresses and usernames are imported into GitLab. + %hr + %p + = button_tag 'Import all projects', class: 'btn btn-success js-import-all' + +%table.table.import-jobs + %thead + %tr + %th From FogBugz + %th To GitLab + %th Status + %tbody + - @already_added_projects.each do |project| + %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} + %td + = project.import_source + %td + %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] + %td.job-status + - if project.import_status == 'finished' + %span + %i.fa.fa-check + done + - elsif project.import_status == 'started' + %i.fa.fa-spinner.fa-spin + started + - else + = project.human_import_status_name + + - @repos.each do |repo| + %tr{id: "repo_#{repo.id}"} + %td + = repo.name + %td.import-target + = "#{current_user.username}/#{repo.name}" + %td.import-actions.job-status + = button_tag "Import", class: "btn js-add-to-import" + +:coffeescript + new ImporterStatus("#{jobs_import_fogbugz_path}", "#{import_fogbugz_path}") diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 636218368cc..bccea21e7a8 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -72,6 +72,11 @@ %i.fa.fa-google Google Code + - if fogbugz_import_enabled? + = link_to new_import_fogbugz_path, class: 'btn import_fogbugz' do + %i.fa.fa-bug + Fogbugz + - if git_import_enabled? = link_to "#", class: 'btn js-toggle-button import_git' do %i.fa.fa-git diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index f2ba2e15e7b..ea2808045eb 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -7,22 +7,31 @@ class RepositoryImportWorker def perform(project_id) project = Project.find(project_id) - import_result = gitlab_shell.send(:import_repository, + unless project.import_url == Project::UNKNOWN_IMPORT_URL + import_result = gitlab_shell.send(:import_repository, project.path_with_namespace, project.import_url) - return project.import_fail unless import_result + return project.import_fail unless import_result + else + unless project.create_repository + return project.import_fail + end + end - data_import_result = if project.import_type == 'github' - Gitlab::GithubImport::Importer.new(project).execute - elsif project.import_type == 'gitlab' - Gitlab::GitlabImport::Importer.new(project).execute - elsif project.import_type == 'bitbucket' - Gitlab::BitbucketImport::Importer.new(project).execute - elsif project.import_type == 'google_code' - Gitlab::GoogleCodeImport::Importer.new(project).execute - else - true - end + data_import_result = case project.import_type + when 'github' + Gitlab::GithubImport::Importer.new(project).execute + when 'gitlab' + Gitlab::GitlabImport::Importer.new(project).execute + when 'bitbucket' + Gitlab::BitbucketImport::Importer.new(project).execute + when 'google_code' + Gitlab::GoogleCodeImport::Importer.new(project).execute + when 'fogbugz' + Gitlab::FogbugzImport::Importer.new(project).execute + else + true + end return project.import_fail unless data_import_result Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket' diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index c47e5dab27c..689c3f3049d 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -158,7 +158,7 @@ Settings.gitlab.default_projects_features['snippets'] = false if Settings. Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root) Settings.gitlab['restricted_signup_domains'] ||= [] -Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','git'] +Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'] # # Reply by email diff --git a/config/routes.rb b/config/routes.rb index 25c286b3083..5bf721d6b13 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -99,6 +99,15 @@ Gitlab::Application.routes.draw do get :new_user_map, path: :user_map post :create_user_map, path: :user_map end + + resource :fogbugz, only: [:create, :new], controller: :fogbugz do + get :status + post :callback + get :jobs + + get :new_user_map, path: :user_map + post :create_user_map, path: :user_map + end end # diff --git a/doc/workflow/importing/README.md b/doc/workflow/importing/README.md index 5cde90993d2..7ccf06fbd60 100644 --- a/doc/workflow/importing/README.md +++ b/doc/workflow/importing/README.md @@ -3,6 +3,7 @@ 1. [Bitbucket](import_projects_from_bitbucket.md) 2. [GitHub](import_projects_from_github.md) 3. [GitLab.com](import_projects_from_gitlab_com.md) +4. [FogBugz](import_projects_from_fogbugz.md) 4. [SVN](migrating_from_svn.md) ### Note diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png new file mode 100644 index 00000000000..205c515bd3f Binary files /dev/null and b/doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png differ diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png new file mode 100644 index 00000000000..a1e348d46ad Binary files /dev/null and b/doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png differ diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png new file mode 100644 index 00000000000..ed362846909 Binary files /dev/null and b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png differ diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png new file mode 100644 index 00000000000..d2fbd0267bd Binary files /dev/null and b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png differ diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png new file mode 100644 index 00000000000..b1cc4b58525 Binary files /dev/null and b/doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png differ diff --git a/doc/workflow/importing/import_projects_from_fogbugz.md b/doc/workflow/importing/import_projects_from_fogbugz.md new file mode 100644 index 00000000000..71af0f9ea44 --- /dev/null +++ b/doc/workflow/importing/import_projects_from_fogbugz.md @@ -0,0 +1,29 @@ +# Import your project from FogBugz to GitLab + +It only takes a few simple steps to import your project from FogBugz. +The importer will import all of your cases and comments with original case +numbers and timestamps. You will also have the opportunity to map FogBugz +users to GitLab users. + +* From your GitLab dashboard click 'New project' + +* Click on the 'FogBugz' button + +![FogBugz](fogbugz_importer/fogbugz_import_select_fogbogz.png) + +* Enter your FogBugz URL, email address, and password. + +![Login](fogbugz_importer/fogbugz_import_login.png) + +* Create mapping from FogBugz users to GitLab users. + +![User Map](fogbugz_importer/fogbugz_import_user_map.png) + +* Select the projects you wish to import by clicking the Import buttons + +![Import Project](fogbugz_importer/fogbugz_import_select_project.png) + +* Once the import has finished click the link to take you to the project +dashboard. Follow the directions to push your existing repository. + +![Finished](fogbugz_importer/fogbugz_import_finished.png) diff --git a/lib/gitlab/fogbugz_import/client.rb b/lib/gitlab/fogbugz_import/client.rb new file mode 100644 index 00000000000..431d50882fd --- /dev/null +++ b/lib/gitlab/fogbugz_import/client.rb @@ -0,0 +1,56 @@ +require 'fogbugz' + +module Gitlab + module FogbugzImport + class Client + attr_reader :api + + def initialize(options = {}) + if options[:uri] && options[:token] + @api = ::Fogbugz::Interface.new(options) + elsif options[:uri] && options[:email] && options[:password] + @api = ::Fogbugz::Interface.new(options) + @api.authenticate + @api + end + end + + def get_token + @api.token + end + + def valid? + !get_token.blank? + end + + def user_map + users = {} + res = @api.command(:listPeople) + res['people']['person'].each do |user| + users[user['ixPerson']] = { name: user['sFullName'], email: user['sEmail'] } + end + users + end + + def repos + res = @api.command(:listProjects) + @repos ||= res['projects']['project'].map { |proj| FogbugzImport::Repository.new(proj) } + end + + def repo(id) + repos.find { |r| r.id.to_s == id.to_s } + end + + def cases(project_id) + project_name = repo(project_id).name + res = @api.command(:search, q: "project:'#{project_name}'", cols: 'ixPersonAssignedTo,ixPersonOpenedBy,ixPersonClosedBy,sStatus,sPriority,sCategory,fOpen,sTitle,sLatestTextSummary,dtOpened,dtClosed,dtResolved,dtLastUpdated,events') + return [] unless res['cases']['count'].to_i > 0 + res['cases']['case'] + end + + def categories + @api.command(:listCategories) + end + end + end +end diff --git a/lib/gitlab/fogbugz_import/importer.rb b/lib/gitlab/fogbugz_import/importer.rb new file mode 100644 index 00000000000..61e08b23543 --- /dev/null +++ b/lib/gitlab/fogbugz_import/importer.rb @@ -0,0 +1,298 @@ +module Gitlab + module FogbugzImport + class Importer + attr_reader :project, :repo + + def initialize(project) + @project = project + + import_data = project.import_data.try(:data) + repo_data = import_data['repo'] if import_data + @repo = FogbugzImport::Repository.new(repo_data) + + @known_labels = Set.new + end + + def execute + return true unless repo.valid? + + data = project.import_data.try(:data) + + client = Gitlab::FogbugzImport::Client.new(token: data['fb_session']['token'], uri: data['fb_session']['uri']) + + @cases = client.cases(@repo.id.to_i) + @categories = client.categories + + import_cases + + true + end + + private + + def user_map + @user_map ||= begin + user_map = Hash.new + import_data = project.import_data.try(:data) + stored_user_map = import_data['user_map'] if import_data + user_map.update(stored_user_map) if stored_user_map + + user_map + end + end + + def import_labels + @categories['categories']['category'].each do |label| + create_label(label['sCategory']) + @known_labels << name + end + end + + def nice_label_color(name) + case name + when 'Blocker' + '#ff0000' + when 'Crash' + '#ffcfcf' + when 'Major' + '#deffcf' + when 'Minor' + '#cfe9ff' + when 'Bug' + '#d9534f' + when 'Feature' + '#44ad8e' + when 'Technical Task' + '#4b6dd0' + else + '#e2e2e2' + end + end + + def create_label(name) + color = nice_label_color(name) + Label.create!(project_id: project.id, title: name, color: color) + end + + def user_info(person_id) + user_hash = user_map[person_id.to_s] + + user_name = '' + gitlab_id = nil + + unless user_hash.nil? + user_name = user_hash['name'] + if user = User.find_by(id: user_hash['gitlab_user']) + user_name = "@#{user.username}" + gitlab_id = user.id + end + end + + { name: user_name, gitlab_id: gitlab_id } + end + + def import_cases + return unless @cases + + while bug = @cases.shift + author = user_info(bug['ixPersonOpenedBy'])[:name] + date = DateTime.parse(bug['dtOpened']) + + comments = bug['events']['event'] + + content = format_content(opened_content(comments)) + body = format_issue_body(author, date, content) + + labels = [] + [bug['sCategory'], bug['sPriority']].each do |label| + unless label.blank? + labels << label + unless @known_labels.include?(label) + create_label(label) + @known_labels << label + end + end + end + + assignee_id = user_info(bug['ixPersonAssignedTo'])[:gitlab_id] + author_id = user_info(bug['ixPersonOpenedBy'])[:gitlab_id] || project.creator_id + + issue = Issue.create!( + project_id: project.id, + title: bug['sTitle'], + description: body, + author_id: author_id, + assignee_id: assignee_id, + state: bug['fOpen'] == 'true' ? 'opened' : 'closed' + ) + issue.add_labels_by_names(labels) + + if issue.iid != bug['ixBug'] + issue.update_attribute(:iid, bug['ixBug']) + end + + import_issue_comments(issue, comments) + + issue.update_attribute(:created_at, date) + + last_update = DateTime.parse(bug['dtLastUpdated']) + issue.update_attribute(:updated_at, last_update) + end + end + + def opened_content(comments) + while comment = comments.shift + if comment['sVerb'] == 'Opened' + return comment['s'] + end + end + '' + end + + def import_issue_comments(issue, comments) + Note.transaction do + while comment = comments.shift + verb = comment['sVerb'] + + next if verb == 'Opened' || verb === 'Closed' + + content = format_content(comment['s']) + attachments = format_attachments(comment['rgAttachments']) + updates = format_updates(comment) + + next if content.blank? && attachments.empty? && updates.empty? + + author = user_info(comment['ixPerson'])[:name] + author_id = user_info(comment['ixPerson'])[:gitlab_id] || project.creator_id + date = DateTime.parse(comment['dt']) + + body = format_issue_comment_body( + comment['ixBugEvent'], + author, + date, + content, + attachments, + updates + ) + + note = Note.create!( + project_id: project.id, + noteable_type: "Issue", + noteable_id: issue.id, + author_id: author_id, + note: body + ) + + note.update_attribute(:created_at, date) + note.update_attribute(:updated_at, date) + end + end + end + + def linkify_issues(s) + s = s.gsub(/([Ii]ssue) ([0-9]+)/, '\1 #\2') + s = s.gsub(/([Cc]ase) ([0-9]+)/, '\1 #\2') + s + end + + def escape_for_markdown(s) + s = s.gsub(/^#/, "\\#") + s = s.gsub(/^-/, "\\-") + s = s.gsub("`", "\\~") + s = s.gsub("\r", "") + s = s.gsub("\n", " \n") + s + end + + def format_content(raw_content) + return raw_content if raw_content.nil? + linkify_issues(escape_for_markdown(raw_content)) + end + + def format_attachments(raw_attachments) + return [] unless raw_attachments + + attachments = case raw_attachments['attachment'] + when Array + raw_attachments['attachment'] + when Hash + [raw_attachments['attachment']] + else + [] + end + + attachments.map! { |a| format_attachment(a) } + attachments.compact + end + + def format_attachment(attachment) + link = build_attachment_url(attachment['sURL']) + + res = ::Projects::DownloadService.new(project, link).execute + + return nil if res.nil? + + text = "[#{res['alt']}](#{res['url']})" + text = "!#{text}" if res['is_image'] + text + end + + def build_attachment_url(rel_url) + data = project.import_data.try(:data) + uri = data['fb_session']['uri'] + token = data['fb_session']['token'] + "#{uri}/#{rel_url}&token=#{token}" + end + + def format_updates(comment) + updates = [] + + if comment['sChanges'] + updates << "*Changes: #{linkify_issues(comment['sChanges'].chomp)}*" + end + + if comment['evtDescription'] + updates << "*#{comment['evtDescription']}*" + end + + updates + end + + def format_issue_body(author, date, content) + body = [] + body << "*By #{author} on #{date} (imported from FogBugz)*" + body << '---' + + if content.blank? + content = '*(No description has been entered for this issue)*' + end + body << content + + body.join("\n\n") + end + + def format_issue_comment_body(id, author, date, content, attachments, updates) + body = [] + body << "*By #{author} on #{date} (imported from FogBugz)*" + body << '---' + + if content.blank? + content = "*(No comment has been entered for this change)*" + end + body << content + + if updates.any? + body << '---' + body += updates + end + + if attachments.any? + body << '---' + body += attachments + end + + body.join("\n\n") + end + end + end +end diff --git a/lib/gitlab/fogbugz_import/project_creator.rb b/lib/gitlab/fogbugz_import/project_creator.rb new file mode 100644 index 00000000000..f02ea43910f --- /dev/null +++ b/lib/gitlab/fogbugz_import/project_creator.rb @@ -0,0 +1,38 @@ +module Gitlab + module FogbugzImport + class ProjectCreator + attr_reader :repo, :fb_session, :namespace, :current_user, :user_map + + def initialize(repo, fb_session, namespace, current_user, user_map = nil) + @repo = repo + @fb_session = fb_session + @namespace = namespace + @current_user = current_user + @user_map = user_map + end + + def execute + project = ::Projects::CreateService.new(current_user, + name: repo.safe_name, + path: repo.path, + namespace: namespace, + creator: current_user, + visibility_level: Gitlab::VisibilityLevel::INTERNAL, + import_type: 'fogbugz', + import_source: repo.name, + import_url: Project::UNKNOWN_IMPORT_URL + ).execute + + import_data = project.create_import_data( + data: { + 'repo' => repo.raw_data, + 'user_map' => user_map, + 'fb_session' => fb_session + } + ) + + project + end + end + end +end diff --git a/lib/gitlab/fogbugz_import/repository.rb b/lib/gitlab/fogbugz_import/repository.rb new file mode 100644 index 00000000000..d1dc63db2b2 --- /dev/null +++ b/lib/gitlab/fogbugz_import/repository.rb @@ -0,0 +1,31 @@ +module Gitlab + module FogbugzImport + class Repository + attr_accessor :raw_data + + def initialize(raw_data) + @raw_data = raw_data + end + + def valid? + raw_data.is_a?(Hash) + end + + def id + raw_data['ixProject'] + end + + def name + raw_data['sProject'] + end + + def safe_name + name.gsub(/[^\s\w.-]/, '') + end + + def path + safe_name.gsub(/[\s]/, '_') + end + end + end +end diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb index 991b70aab6a..ccfdfbe73e8 100644 --- a/lib/gitlab/import_sources.rb +++ b/lib/gitlab/import_sources.rb @@ -19,6 +19,7 @@ module Gitlab 'GitLab.com' => 'gitlab', 'Gitorious.org' => 'gitorious', 'Google Code' => 'google_code', + 'FogBugz' => 'fogbugz', 'Any repo by URL' => 'git', } end diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb new file mode 100644 index 00000000000..27b11267d2a --- /dev/null +++ b/spec/controllers/import/fogbugz_controller_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' +require_relative 'import_spec_helper' + +describe Import::FogbugzController do + include ImportSpecHelper + + let(:user) { create(:user) } + + before do + sign_in(user) + end + + describe 'GET status' do + before do + @repo = OpenStruct.new(name: 'vim') + stub_client(valid?: true) + end + + it 'assigns variables' do + @project = create(:project, import_type: 'fogbugz', creator_id: user.id) + stub_client(repos: [@repo]) + + get :status + + expect(assigns(:already_added_projects)).to eq([@project]) + expect(assigns(:repos)).to eq([@repo]) + end + + it 'does not show already added project' do + @project = create(:project, import_type: 'fogbugz', creator_id: user.id, import_source: 'vim') + stub_client(repos: [@repo]) + + get :status + + expect(assigns(:already_added_projects)).to eq([@project]) + expect(assigns(:repos)).to eq([]) + end + end +end diff --git a/spec/services/projects/download_service_spec.rb b/spec/services/projects/download_service_spec.rb new file mode 100644 index 00000000000..f12e09c58c3 --- /dev/null +++ b/spec/services/projects/download_service_spec.rb @@ -0,0 +1,65 @@ +require 'spec_helper' + +describe Projects::DownloadService do + describe 'File service' do + before do + @user = create :user + @project = create :project, creator_id: @user.id, namespace: @user.namespace + end + + context 'for a URL that is not on whitelist' do + before do + url = 'https://code.jquery.com/jquery-2.1.4.min.js' + @link_to_file = download_file(@project, url) + end + + it { expect(@link_to_file).to eq(nil) } + end + + context 'for URLs that are on the whitelist' do + before do + sham_rack_app = ShamRack.at('mycompany.fogbugz.com').stub + sham_rack_app.register_resource('/rails_sample.jpg', File.read(Rails.root + 'spec/fixtures/rails_sample.jpg'), 'image/jpg') + sham_rack_app.register_resource('/doc_sample.txt', File.read(Rails.root + 'spec/fixtures/doc_sample.txt'), 'text/plain') + end + + after do + ShamRack.unmount_all + end + + context 'an image file' do + before do + url = 'http://mycompany.fogbugz.com/rails_sample.jpg' + @link_to_file = download_file(@project, url) + end + + it { expect(@link_to_file).to have_key('alt') } + it { expect(@link_to_file).to have_key('url') } + it { expect(@link_to_file).to have_key('is_image') } + it { expect(@link_to_file['is_image']).to be true } + it { expect(@link_to_file['url']).to match("/#{@project.path_with_namespace}") } + it { expect(@link_to_file['url']).to match('rails_sample.jpg') } + it { expect(@link_to_file['alt']).to eq('rails_sample') } + end + + context 'a txt file' do + before do + url = 'http://mycompany.fogbugz.com/doc_sample.txt' + @link_to_file = download_file(@project, url) + end + + it { expect(@link_to_file).to have_key('alt') } + it { expect(@link_to_file).to have_key('url') } + it { expect(@link_to_file).to have_key('is_image') } + it { expect(@link_to_file['is_image']).to be false } + it { expect(@link_to_file['url']).to match("/#{@project.path_with_namespace}") } + it { expect(@link_to_file['url']).to match('doc_sample.txt') } + it { expect(@link_to_file['alt']).to eq('doc_sample.txt') } + end + end + end + + def download_file(repository, url) + Projects::DownloadService.new(repository, url).execute + end +end -- cgit v1.2.1 From c9d78a00c583c0439aeea7416eeea2e50e0d59e4 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 9 Sep 2015 11:36:55 +0200 Subject: Fix UI bugs with discussions Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/generic/timeline.scss | 19 ++++++++++++++++++- app/assets/stylesheets/pages/note_form.scss | 6 +++--- app/views/projects/notes/_discussion.html.haml | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/generic/timeline.scss b/app/assets/stylesheets/generic/timeline.scss index 668a6f848cc..74bbaabad39 100644 --- a/app/assets/stylesheets/generic/timeline.scss +++ b/app/assets/stylesheets/generic/timeline.scss @@ -4,14 +4,19 @@ margin: 0; padding: 0; - > li { + .timeline-entry { padding: $gl-padding; border-color: #f1f2f4; margin-left: -$gl-padding; margin-right: -$gl-padding; color: $gl-gray; + border-bottom: 1px solid #f1f2f4; border-right: 1px solid #f1f2f4; + &:last-child { + border-bottom: none; + } + .avatar { margin-right: 15px; } @@ -33,6 +38,13 @@ color: $gl-gray !important; } } + + .diff-file { + border: 1px solid $border-color; + border-bottom: none; + margin-left: 0; + margin-right: 0; + } } @media (max-width: $screen-xs-max) { @@ -51,3 +63,8 @@ } } } + +.discussion .timeline-entry { + margin: 0; + border-right: none; +} diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 85804f5ee61..b311d26d675 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -146,9 +146,9 @@ } .discussion-reply-holder { - background: #f9f9f9; + background: $background-color; padding: 10px 15px; - border-top: 1px solid #DDD; + border-top: 1px solid $border-color; } } @@ -170,6 +170,6 @@ background: #FFF; padding: 5px; margin-top: -11px; - border: 1px solid #DDD; + border: 1px solid $border-color; font-size: 13px; } diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml index 6daf2d15d07..b8068835b3a 100644 --- a/app/views/projects/notes/_discussion.html.haml +++ b/app/views/projects/notes/_discussion.html.haml @@ -1,5 +1,5 @@ - note = discussion_notes.first -.timeline-entry.prepend-top-default +.timeline-entry .timeline-entry-inner .timeline-icon = link_to user_path(note.author) do -- cgit v1.2.1 From d3730b071365dd3dbfa0b8ec4433e1f18a93c969 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 9 Sep 2015 14:54:34 +0100 Subject: Fix highlighting of deleted lines in diffs. --- CHANGELOG | 1 + config/initializers/rouge_diff_lexer.rb | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 config/initializers/rouge_diff_lexer.rb diff --git a/CHANGELOG b/CHANGELOG index 247eb1e3643..ddb31fc430f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -40,6 +40,7 @@ v 8.0.0 (unreleased) - Add ability to get user information by ID of an SSH key via the API - Fix bug which IE cannot show image at markdown when the image is raw file of gitlab - Add support for Crowd + - Fix highlighting of deleted lines in diffs. v 7.14.1 - Improve abuse reports management from admin area diff --git a/config/initializers/rouge_diff_lexer.rb b/config/initializers/rouge_diff_lexer.rb new file mode 100644 index 00000000000..fdb2d7b748e --- /dev/null +++ b/config/initializers/rouge_diff_lexer.rb @@ -0,0 +1,24 @@ +# Here until https://github.com/jneen/rouge/pull/297 is merged into Rouge and the gem is updated in GitLab. +module Rouge + module Lexers + class Diff + def self.analyze_text(text) + return 1 if text.start_with?('Index: ') + return 1 if text.start_with?('diff ') + return 0.9 if text.start_with?('--- ') + end + + state :root do + rule(/^ .*\n/, Text) + rule(/^---\n/, Text) + rule(/^\+.*\n/, Generic::Inserted) + rule(/^-+.*\n/, Generic::Deleted) + rule(/^!.*\n/, Generic::Strong) + rule(/^@.*\n/, Generic::Subheading) + rule(/^([Ii]ndex|diff).*\n/, Generic::Heading) + rule(/^=.*\n/, Generic::Heading) + rule(/.*\n/, Text) + end + end + end +end -- cgit v1.2.1 From 0d66d4d342c72d141578d746aad766a6234fc872 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 9 Sep 2015 15:19:58 +0100 Subject: Fix reading session_expire_delay when application settings are not yet created and migrations are not yet done --- config/initializers/session_store.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 6d274cd95a1..88651394d1d 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -2,7 +2,12 @@ require 'gitlab/current_settings' include Gitlab::CurrentSettings -Settings.gitlab['session_expire_delay'] = current_application_settings.session_expire_delay + +# allow it to fail: it may to do so when create_from_defaults is executed before migrations are actually done +begin + Settings.gitlab['session_expire_delay'] = current_application_settings.session_expire_delay +rescue +end Gitlab::Application.config.session_store( :redis_store, # Using the cookie_store would enable session replay attacks. -- cgit v1.2.1 From fa40759768518d3457cc95204d6496db999aa7ca Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 9 Sep 2015 22:36:13 +0200 Subject: Separate profile settings link from the rest on sidebar Signed-off-by: Dmitriy Zaporozhets --- app/views/layouts/nav/_dashboard.html.haml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 0cf1c3d5d27..7d3764a76a3 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -37,14 +37,15 @@ = icon('clipboard fw') %span Snippets + = nav_link(controller: :help) do + = link_to help_path, title: 'Help', data: {placement: 'right'} do + = icon('question-circle fw') + %span + Help - if current_user + %li.separate-item = nav_link(controller: :profile) do = link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('user fw') %span Profile Settings - = nav_link(controller: :help) do - = link_to help_path, title: 'Help', data: {placement: 'right'} do - = icon('question-circle fw') - %span - Help -- cgit v1.2.1 From 1e3ce07714efcc5ac18bb2f167c5b4956e114839 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 9 Sep 2015 23:05:47 +0200 Subject: Use page title for header title too Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/generic/blocks.scss | 4 ++++ app/views/layouts/nav/_profile.html.haml | 2 +- app/views/layouts/profile.html.haml | 3 ++- app/views/profiles/accounts/show.html.haml | 9 +++------ app/views/profiles/applications.html.haml | 9 ++++----- app/views/profiles/audit_log.html.haml | 9 ++++++--- app/views/profiles/emails/index.html.haml | 10 ++++------ app/views/profiles/keys/index.html.haml | 13 +++++++------ app/views/profiles/notifications/show.html.haml | 8 ++++---- app/views/profiles/passwords/edit.html.haml | 10 +++++----- app/views/profiles/passwords/new.html.haml | 2 +- app/views/profiles/preferences/show.html.haml | 8 ++++---- app/views/profiles/show.html.haml | 9 ++------- 13 files changed, 47 insertions(+), 49 deletions(-) diff --git a/app/assets/stylesheets/generic/blocks.scss b/app/assets/stylesheets/generic/blocks.scss index 27a4c4db8c8..48d9f890f62 100644 --- a/app/assets/stylesheets/generic/blocks.scss +++ b/app/assets/stylesheets/generic/blocks.scss @@ -27,6 +27,10 @@ border-bottom: 1px solid #e7e9ed; color: $gl-gray; + &.top-block { + border-top: none; + } + &.middle-block { margin-top: 0; margin-bottom: 0; diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index 33fd5fcef6c..abdb7544651 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -11,7 +11,7 @@ = link_to profile_path, title: 'Profile', data: {placement: 'right'} do = icon('user fw') %span - Profile + Profile Settings = nav_link(controller: [:accounts, :two_factor_auths]) do = link_to profile_account_path, title: 'Account', data: {placement: 'right'} do = icon('gear fw') diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml index 77d2ccbf762..b80ce0dfc75 100644 --- a/app/views/layouts/profile.html.haml +++ b/app/views/layouts/profile.html.haml @@ -1,5 +1,6 @@ - page_title "Profile Settings" -- header_title "Profile Settings", profile_path +- unless @header_title + - header_title "Profile Settings", profile_path - sidebar "profile" = render template: "layouts/application" diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 767fe2e0e9a..2d2a9ac8009 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -1,9 +1,6 @@ - page_title "Account" -%h3.page-title - = page_title -%p.light - Change your username and basic account settings. -%hr +- header_title page_title, profile_account_path + - if current_user.ldap_user? .alert.alert-info Some options are unavailable for LDAP accounts @@ -69,7 +66,7 @@ - button_based_providers.each do |provider| .btn-group = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true" - + - if auth_active?(provider) = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do = icon('close') diff --git a/app/views/profiles/applications.html.haml b/app/views/profiles/applications.html.haml index 3a3e6e1b1c4..2342936a5d5 100644 --- a/app/views/profiles/applications.html.haml +++ b/app/views/profiles/applications.html.haml @@ -1,13 +1,12 @@ - page_title "Applications" -%h3.page-title - = page_title -%p.light +- header_title page_title, applications_profile_path + +.gray-content-block.top-block - if user_oauth_applications? - Manage applications that can use GitLab as an OAuth provider, + Manage applications that can use GitLab as an OAuth provider, and applications that you've authorized to use your account. - else Manage applications that you've authorized to use your account. -%hr - if user_oauth_applications? .oauth-applications diff --git a/app/views/profiles/audit_log.html.haml b/app/views/profiles/audit_log.html.haml index 698d6037428..8fdba45b193 100644 --- a/app/views/profiles/audit_log.html.haml +++ b/app/views/profiles/audit_log.html.haml @@ -1,5 +1,8 @@ - page_title "Audit Log" -%h3.page-title Audit Log -%p.light History of authentications +- header_title page_title, audit_log_profile_path -= render 'event_table', events: @events \ No newline at end of file +.gray-content-block.top-block + History of authentications + +.prepend-top-default += render 'event_table', events: @events diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml index 66812872c41..1d140347a5f 100644 --- a/app/views/profiles/emails/index.html.haml +++ b/app/views/profiles/emails/index.html.haml @@ -1,12 +1,10 @@ - page_title "Emails" -%h3.page-title - = page_title -%p.light - Control emails linked to your account -%hr +- header_title page_title, profile_emails_path +.gray-content-block.top-block + Control emails linked to your account -%ul +%ul.prepend-top-default %li Your %b Primary Email diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml index 06655f7ba3a..14adba1c797 100644 --- a/app/views/profiles/keys/index.html.haml +++ b/app/views/profiles/keys/index.html.haml @@ -1,11 +1,12 @@ - page_title "SSH Keys" -%h3.page-title - = page_title +- header_title page_title, profile_keys_path + +.gray-content-block.top-block .pull-right = link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new" -%p.light - Before you can add an SSH key you need to - = link_to "generate it.", help_page_path("ssh", "README") -%hr + .oneline + Before you can add an SSH key you need to + = link_to "generate it.", help_page_path("ssh", "README") +.prepend-top-default = render 'key_table' diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml index db7fa2eabe3..ea4e5f3e182 100644 --- a/app/views/profiles/notifications/show.html.haml +++ b/app/views/profiles/notifications/show.html.haml @@ -1,10 +1,10 @@ - page_title "Notifications" -%h3.page-title - = page_title -%p.light +- header_title page_title, profile_notifications_path + +.gray-content-block.top-block These are your global notification settings. -%hr +.prepend-top-default = form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f| -if @user.errors.any? %div.alert.alert-danger diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml index 399ae98adf9..fab7c45c9b2 100644 --- a/app/views/profiles/passwords/edit.html.haml +++ b/app/views/profiles/passwords/edit.html.haml @@ -1,13 +1,13 @@ - page_title "Password" -%h3.page-title - = page_title -%p.light +- header_title page_title, edit_profile_password_path + +.gray-content-block.top-block - if @user.password_automatically_set? Set your password. - else Change your password or recover your current one. -%hr -.update-password + +.update-password.prepend-top-default = form_for @user, url: profile_password_path, method: :put, html: { class: 'form-horizontal' } do |f| %div %p.slead diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml index 9c6204963e0..d165f758c81 100644 --- a/app/views/profiles/passwords/new.html.haml +++ b/app/views/profiles/passwords/new.html.haml @@ -12,7 +12,7 @@ %ul - @user.errors.full_messages.each do |msg| %li= msg - + - unless @user.password_automatically_set? .form-group = f.label :current_password, class: 'control-label' diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index aa0361a0a1b..f8cbdb79329 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -1,11 +1,11 @@ - page_title 'Preferences' -%h3.page-title - = page_title -%p.light +- header_title page_title, profile_preferences_path + +.gray-content-block.top-block These settings allow you to customize the appearance and behavior of the site. They are saved with your account and will persist to any device you use to access the site. -%hr +.prepend-top-default = form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'js-preferences-form form-horizontal'} do |f| .panel.panel-default.application-theme diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index c519e52e596..47412e2ef0c 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -1,14 +1,9 @@ -- page_title "Profile" -%h3.page-title - = page_title -%p.light +.gray-content-block.top-block This information will appear on your profile. - if current_user.ldap_user? Some options are unavailable for LDAP accounts -%hr - - +.prepend-top-default = form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f| -if @user.errors.any? %div.alert.alert-danger -- cgit v1.2.1 From 10b6a9248159830f45012a1d551e82d86aeb75d0 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 9 Sep 2015 23:29:19 +0200 Subject: Style panels and add blank container Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/base/gl_bootstrap.scss | 14 +++++++++++++- app/assets/stylesheets/base/gl_variables.scss | 11 ++++++----- app/assets/stylesheets/generic/buttons.scss | 2 +- app/assets/stylesheets/generic/sidebar.scss | 6 ++++++ app/helpers/page_layout_helper.rb | 22 ++++++++++++++++++++++ app/views/layouts/_page.html.haml | 2 +- app/views/profiles/preferences/show.html.haml | 4 ++-- app/views/projects/edit.html.haml | 7 ++++--- 8 files changed, 55 insertions(+), 13 deletions(-) diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index ae72c5b8d97..94508b902c4 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -157,8 +157,10 @@ * */ .panel { + box-shadow: none; .panel-heading { - font-weight: bold; + font-size: 17px; + line-height: 38px; .panel-head-actions { position: relative; @@ -182,6 +184,10 @@ .pagination { margin: 0; } + + .btn { + min-width: 124px; + } } &.panel-small { @@ -209,6 +215,12 @@ } } +.alert-help { + background-color: $background-color; + border: 1px solid $border-color; + color: $gl-gray; +} + // Typography ================================================================= .text-primary, diff --git a/app/assets/stylesheets/base/gl_variables.scss b/app/assets/stylesheets/base/gl_variables.scss index d18b48eaca9..bfef5f78f83 100644 --- a/app/assets/stylesheets/base/gl_variables.scss +++ b/app/assets/stylesheets/base/gl_variables.scss @@ -114,11 +114,12 @@ $alert-border-radius: 0; // //## -$panel-border-radius: 0; -$panel-default-text: $text-color; -$panel-default-border: #E7E9ED; -$panel-default-heading-bg: #F8FAFC; - +$panel-border-radius: 2px; +$panel-default-text: $text-color; +$panel-default-border: $border-color; +$panel-default-heading-bg: $background-color; +$panel-footer-bg: $background-color; +$panel-inner-border: $border-color; //== Wells // diff --git a/app/assets/stylesheets/generic/buttons.scss b/app/assets/stylesheets/generic/buttons.scss index e8237509092..46ef595ddf0 100644 --- a/app/assets/stylesheets/generic/buttons.scss +++ b/app/assets/stylesheets/generic/buttons.scss @@ -10,7 +10,7 @@ } &.btn-save { - @extend .btn-primary; + @extend .btn-success; } &.btn-remove { diff --git a/app/assets/stylesheets/generic/sidebar.scss b/app/assets/stylesheets/generic/sidebar.scss index 22720c2e1d5..f501bd579e3 100644 --- a/app/assets/stylesheets/generic/sidebar.scss +++ b/app/assets/stylesheets/generic/sidebar.scss @@ -28,6 +28,12 @@ padding: $gl-padding; border: 1px solid #e7e9ed; min-height: 90vh; + + &.container-blank { + background: none; + padding: 0; + border: none; + } } } diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb index 8473d6d75d0..bfbaf11c25a 100644 --- a/app/helpers/page_layout_helper.rb +++ b/app/helpers/page_layout_helper.rb @@ -31,4 +31,26 @@ module PageLayoutHelper @fluid_layout end end + + def blank_container(enabled = false) + if @blank_container.nil? + @blank_container = enabled + else + @blank_container + end + end + + def container_class + css_class = "container-fluid" + + if fluid_layout + css_class += " container-limited" + end + + if blank_container + css_class += " container-blank" + end + + css_class + end end diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index c1746676ae2..707905ee92a 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -19,7 +19,7 @@ = current_user.username .content-wrapper = render "layouts/flash" - %div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" } + %div{ class: container_class } .content .clearfix = yield diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index f8cbdb79329..60289bfe7cd 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -1,11 +1,11 @@ - page_title 'Preferences' - header_title page_title, profile_preferences_path +- @blank_container = true -.gray-content-block.top-block +.alert.alert-help These settings allow you to customize the appearance and behavior of the site. They are saved with your account and will persist to any device you use to access the site. -.prepend-top-default = form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'js-preferences-form form-horizontal'} do |f| .panel.panel-default.application-theme diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index e8e65d87f47..90dce739992 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -1,10 +1,11 @@ +- @blank_container = true + .project-edit-container .project-edit-errors .project-edit-content - %div - %h3.page-title + .panel.panel-default + .panel-heading Project settings - %hr .panel-body = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f| -- cgit v1.2.1 From 12ad9b4ba0341ac7b5012dd52b1d6cd6e68f778a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 9 Sep 2015 23:38:27 +0200 Subject: Enable blank container for group settings page Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/base/gl_bootstrap.scss | 10 +++++++--- app/views/groups/edit.html.haml | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss index 94508b902c4..eb8d23d6453 100644 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ b/app/assets/stylesheets/base/gl_bootstrap.scss @@ -156,12 +156,16 @@ * Add some extra stuff to panels * */ + +.container-blank .panel .panel-heading { + font-size: 17px; + line-height: 38px; +} + .panel { box-shadow: none; - .panel-heading { - font-size: 17px; - line-height: 38px; + .panel-heading { .panel-head-actions { position: relative; top: -5px; diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 2ff4b7e23ea..ac7d9ba0f4f 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -1,3 +1,4 @@ +- @blank_container = true .panel.panel-default .panel-heading %strong= @group.name -- cgit v1.2.1 From 960a1880ab09f8c12d6f7a7c22296c876ddad1ac Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 9 Sep 2015 23:49:34 +0200 Subject: Fix last element of sidebar being hidden for small screens Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/generic/sidebar.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/generic/sidebar.scss b/app/assets/stylesheets/generic/sidebar.scss index f501bd579e3..41ffd358576 100644 --- a/app/assets/stylesheets/generic/sidebar.scss +++ b/app/assets/stylesheets/generic/sidebar.scss @@ -39,7 +39,7 @@ .nav-sidebar { margin-top: 14 + $header-height; - margin-bottom: 50px; + margin-bottom: 100px; transition-duration: .3s; list-style: none; overflow: hidden; -- cgit v1.2.1 From def939a5628fb3df24b39dbe7b39636968c294ed Mon Sep 17 00:00:00 2001 From: Darby Date: Wed, 9 Sep 2015 15:04:38 -0700 Subject: Turned off autocomplete for new issue titles --- app/views/shared/issuable/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 09327d645f3..1aa1e3c6c97 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -9,7 +9,7 @@ = f.label :title, class: 'control-label' do %strong= 'Title *' .col-sm-10 - = f.text_field :title, maxlength: 255, autofocus: true, + = f.text_field :title, maxlength: 255, autofocus: true, autocomplete: 'off', class: 'form-control pad js-gfm-input', required: true - if issuable.is_a?(MergeRequest) -- cgit v1.2.1 From a0359fbd77c0a4fcbac30c15544b1a3432bfe8bf Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 10 Sep 2015 00:34:09 +0200 Subject: Improve accounts page UI Signed-off-by: Dmitriy Zaporozhets --- app/views/profiles/accounts/show.html.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 2d2a9ac8009..cd7b1b0fe03 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -1,5 +1,6 @@ - page_title "Account" - header_title page_title, profile_account_path +- @blank_container = true - if current_user.ldap_user? .alert.alert-info -- cgit v1.2.1 From 19cba632d846c9fcf736133eb62db1b8905c5009 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 9 Sep 2015 21:20:51 -0300 Subject: fix 7.14 stable branch name --- doc/update/6.x-or-7.x-to-7.14.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/update/6.x-or-7.x-to-7.14.md b/doc/update/6.x-or-7.x-to-7.14.md index 5bc1f84270a..b34fb12da6f 100644 --- a/doc/update/6.x-or-7.x-to-7.14.md +++ b/doc/update/6.x-or-7.x-to-7.14.md @@ -162,7 +162,7 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab TIP: to see what changed in `gitlab.yml.example` in this release use next command: ``` -git diff 6-0-stable:config/gitlab.yml.example 7.14-stable:config/gitlab.yml.example +git diff 6-0-stable:config/gitlab.yml.example 7-14-stable:config/gitlab.yml.example ``` * Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/gitlab.yml.example but with your settings. -- cgit v1.2.1 From 253bc0ca15a9b2f459aef94a33de926984747f35 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 10 Sep 2015 00:19:53 -0700 Subject: Fix test --- features/steps/admin/users.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb index 2e17d5c4c2e..4bc290b6bdf 100644 --- a/features/steps/admin/users.rb +++ b/features/steps/admin/users.rb @@ -4,11 +4,13 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps include SharedAdmin before do - allow(Devise).to receive(:omniauth_providers).and_return([:twitter, :twitter_updated]) + allow(Gitlab::OAuth::Provider).to receive(:providers).and_return([:twitter, :twitter_updated]) + allow_any_instance_of(ApplicationHelper).to receive(:user_omniauth_authorize_path).and_return(root_path) end after do - allow(Devise).to receive(:omniauth_providers).and_call_original + allow(Gitlab::OAuth::Provider).to receive(:providers).and_call_original + allow_any_instance_of(ApplicationHelper).to receive(:user_omniauth_authorize_path).and_call_original end step 'I should see all users' do -- cgit v1.2.1 From af3b6f6362d34077d100385b71f9fe2a0ce8a446 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 10 Sep 2015 09:51:37 +0200 Subject: Fix fixed layout Signed-off-by: Dmitriy Zaporozhets --- app/helpers/page_layout_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb index bfbaf11c25a..df37be51ce9 100644 --- a/app/helpers/page_layout_helper.rb +++ b/app/helpers/page_layout_helper.rb @@ -43,7 +43,7 @@ module PageLayoutHelper def container_class css_class = "container-fluid" - if fluid_layout + unless fluid_layout css_class += " container-limited" end -- cgit v1.2.1