Add ProjectLabel model
This commit is contained in:
parent
e2dd75c0a2
commit
cfedd42bad
16 changed files with 73 additions and 50 deletions
|
@ -128,7 +128,8 @@ class IssuableFinder
|
|||
@labels = Label.where(title: label_names)
|
||||
|
||||
if projects
|
||||
@labels = @labels.where(project: projects)
|
||||
label_ids = LabelsFinder.new(current_user, project_id: projects).execute.select(:id)
|
||||
@labels = @labels.where(labels: { id: label_ids })
|
||||
end
|
||||
else
|
||||
@labels = Label.none
|
||||
|
|
|
@ -57,21 +57,21 @@ module LabelsHelper
|
|||
def edit_label_path(label)
|
||||
case label
|
||||
when GroupLabel then edit_group_label_path(label.group, label)
|
||||
else edit_namespace_project_label_path(label.project.namespace, label.project, label)
|
||||
when ProjectLabel then edit_namespace_project_label_path(label.project.namespace, label.project, label)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_label_path(label)
|
||||
case label
|
||||
when GroupLabel then group_label_path(label.group, label)
|
||||
else namespace_project_label_path(label.project.namespace, label.project, label)
|
||||
when ProjectLabel then namespace_project_label_path(label.project.namespace, label.project, label)
|
||||
end
|
||||
end
|
||||
|
||||
def toggle_subscription_label_path(label)
|
||||
case label
|
||||
when GroupLabel then toggle_subscription_group_label_path(label.group, label)
|
||||
else toggle_subscription_namespace_project_label_path(label.project.namespace, label.project, label)
|
||||
when ProjectLabel then toggle_subscription_namespace_project_label_path(label.project.namespace, label.project, label)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -79,7 +79,7 @@ module LabelsHelper
|
|||
title, icon =
|
||||
case label
|
||||
when GroupLabel then ['Group', 'folder-open']
|
||||
else ['Project', 'bookmark']
|
||||
when ProjectLabel then ['Project', 'bookmark']
|
||||
end
|
||||
|
||||
options[:class] ||= ''
|
||||
|
|
|
@ -15,15 +15,12 @@ class Label < ActiveRecord::Base
|
|||
|
||||
default_value_for :color, DEFAULT_COLOR
|
||||
|
||||
belongs_to :project
|
||||
|
||||
has_many :lists, dependent: :destroy
|
||||
has_many :label_links, dependent: :destroy
|
||||
has_many :issues, through: :label_links, source: :target, source_type: 'Issue'
|
||||
has_many :merge_requests, through: :label_links, source: :target, source_type: 'MergeRequest'
|
||||
|
||||
validates :color, color: true, allow_blank: false
|
||||
validates :project, presence: true, if: :project_label?
|
||||
|
||||
# Don't allow ',' for label titles
|
||||
validates :title, presence: true, format: { with: /\A[^,]+\z/ }
|
||||
|
@ -137,10 +134,6 @@ class Label < ActiveRecord::Base
|
|||
.count
|
||||
end
|
||||
|
||||
def project_label?
|
||||
type.blank? && !template?
|
||||
end
|
||||
|
||||
def label_format_reference(format = :id)
|
||||
raise StandardError, 'Unknown format' unless [:id, :name].include?(format)
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ class Project < ActiveRecord::Base
|
|||
# Merge requests from source project should be kept when source project was removed
|
||||
has_many :fork_merge_requests, foreign_key: 'source_project_id', class_name: MergeRequest
|
||||
has_many :issues, dependent: :destroy
|
||||
has_many :labels, dependent: :destroy
|
||||
has_many :labels, dependent: :destroy, class_name: 'ProjectLabel'
|
||||
has_many :services, dependent: :destroy
|
||||
has_many :events, dependent: :destroy
|
||||
has_many :milestones, dependent: :destroy
|
||||
|
@ -730,8 +730,10 @@ class Project < ActiveRecord::Base
|
|||
def create_labels
|
||||
Label.templates.each do |label|
|
||||
label = label.dup
|
||||
label.template = nil
|
||||
label.template = false
|
||||
label.project_id = self.id
|
||||
label.type = 'ProjectLabel'
|
||||
|
||||
label.save
|
||||
end
|
||||
end
|
||||
|
|
5
app/models/project_label.rb
Normal file
5
app/models/project_label.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class ProjectLabel < Label
|
||||
belongs_to :project
|
||||
|
||||
validates :project, presence: true
|
||||
end
|
|
@ -1,7 +1,5 @@
|
|||
class LabelPolicy < BasePolicy
|
||||
class ProjectLabelPolicy < BasePolicy
|
||||
def rules
|
||||
return unless @user
|
||||
|
||||
can! :admin_label if Ability.allowed?(@user, :admin_label, @subject.project)
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
= form_for [@project.namespace.becomes(Namespace), @project, @label], html: { class: 'form-horizontal label-form js-quick-submit js-requires-input' } do |f|
|
||||
= form_for @label, as: :label, url: url, html: { class: 'form-horizontal label-form js-quick-submit js-requires-input' } do |f|
|
||||
= form_errors(@label)
|
||||
|
||||
.form-group
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
= icon('bookmark')
|
||||
Edit Project Label
|
||||
%hr
|
||||
= render 'form'
|
||||
= render 'form', url: namespace_project_label_path(@project.namespace.becomes(Namespace), @project, @label)
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
= icon('bookmark')
|
||||
New Project Label
|
||||
%hr
|
||||
= render 'form'
|
||||
= render 'form', url: namespace_project_labels_path(@project.namespace.becomes(Namespace), @project)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
class SetProjectLabelTypeOnLabels < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
update_column_in_batches(:labels, :type, 'ProjectLabel') do |table, query|
|
||||
query.where(table[:project_id].not_eq(nil))
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
update_column_in_batches(:labels, :type, nil) do |table, query|
|
||||
query.where(table[:project_id].not_eq(nil))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -70,7 +70,7 @@ module Banzai
|
|||
end
|
||||
|
||||
def object_link_text(object, matches)
|
||||
if object.project.nil? || object.project == context[:project]
|
||||
if object.is_a?(GroupLabel) || object.project == context[:project]
|
||||
LabelsHelper.render_colored_label(object)
|
||||
else
|
||||
LabelsHelper.render_colored_cross_project_label(object)
|
||||
|
|
|
@ -237,7 +237,7 @@ module Gitlab
|
|||
|
||||
def create_label(name)
|
||||
color = nice_label_color(name)
|
||||
Label.create!(project_id: project.id, name: name, color: color)
|
||||
project.labels.create!(name: name, color: color)
|
||||
end
|
||||
|
||||
def format_content(raw_content)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
FactoryGirl.define do
|
||||
factory :label do
|
||||
factory :label, class: ProjectLabel do
|
||||
sequence(:title) { |n| "label#{n}" }
|
||||
color "#990000"
|
||||
project
|
||||
|
|
|
@ -1,47 +1,41 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Label, models: true do
|
||||
let(:label) { create(:label) }
|
||||
describe 'modules' do
|
||||
it { is_expected.to include_module(Referable) }
|
||||
it { is_expected.to include_module(Subscribable) }
|
||||
end
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
|
||||
it { is_expected.to have_many(:label_links).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:issues).through(:label_links).source(:target) }
|
||||
it { is_expected.to have_many(:label_links).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:lists).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe 'modules' do
|
||||
subject { described_class }
|
||||
|
||||
it { is_expected.to include_module(Referable) }
|
||||
end
|
||||
|
||||
describe 'validation' do
|
||||
it { is_expected.to validate_presence_of(:project) }
|
||||
it { is_expected.to validate_uniqueness_of(:title) }
|
||||
|
||||
it 'validates color code' do
|
||||
expect(label).not_to allow_value('G-ITLAB').for(:color)
|
||||
expect(label).not_to allow_value('AABBCC').for(:color)
|
||||
expect(label).not_to allow_value('#AABBCCEE').for(:color)
|
||||
expect(label).not_to allow_value('GGHHII').for(:color)
|
||||
expect(label).not_to allow_value('#').for(:color)
|
||||
expect(label).not_to allow_value('').for(:color)
|
||||
is_expected.not_to allow_value('G-ITLAB').for(:color)
|
||||
is_expected.not_to allow_value('AABBCC').for(:color)
|
||||
is_expected.not_to allow_value('#AABBCCEE').for(:color)
|
||||
is_expected.not_to allow_value('GGHHII').for(:color)
|
||||
is_expected.not_to allow_value('#').for(:color)
|
||||
is_expected.not_to allow_value('').for(:color)
|
||||
|
||||
expect(label).to allow_value('#AABBCC').for(:color)
|
||||
expect(label).to allow_value('#abcdef').for(:color)
|
||||
is_expected.to allow_value('#AABBCC').for(:color)
|
||||
is_expected.to allow_value('#abcdef').for(:color)
|
||||
end
|
||||
|
||||
it 'validates title' do
|
||||
expect(label).not_to allow_value('G,ITLAB').for(:title)
|
||||
expect(label).not_to allow_value('').for(:title)
|
||||
is_expected.not_to allow_value('G,ITLAB').for(:title)
|
||||
is_expected.not_to allow_value('').for(:title)
|
||||
|
||||
expect(label).to allow_value('GITLAB').for(:title)
|
||||
expect(label).to allow_value('gitlab').for(:title)
|
||||
expect(label).to allow_value('G?ITLAB').for(:title)
|
||||
expect(label).to allow_value('G&ITLAB').for(:title)
|
||||
expect(label).to allow_value("customer's request").for(:title)
|
||||
is_expected.to allow_value('GITLAB').for(:title)
|
||||
is_expected.to allow_value('gitlab').for(:title)
|
||||
is_expected.to allow_value('G?ITLAB').for(:title)
|
||||
is_expected.to allow_value('G&ITLAB').for(:title)
|
||||
is_expected.to allow_value("customer's request").for(:title)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -53,6 +47,8 @@ describe Label, models: true do
|
|||
end
|
||||
|
||||
describe '#to_reference' do
|
||||
let(:label) { create(:label) }
|
||||
|
||||
context 'using id' do
|
||||
it 'returns a String reference to the object' do
|
||||
expect(label.to_reference).to eq "~#{label.id}"
|
||||
|
|
11
spec/models/project_label_spec.rb
Normal file
11
spec/models/project_label_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ProjectLabel, models: true do
|
||||
describe 'relationships' do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:project) }
|
||||
end
|
||||
end
|
|
@ -56,7 +56,7 @@ describe Project, models: true do
|
|||
it { is_expected.to have_many(:runners) }
|
||||
it { is_expected.to have_many(:variables) }
|
||||
it { is_expected.to have_many(:triggers) }
|
||||
it { is_expected.to have_many(:labels).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:labels).class_name('ProjectLabel').dependent(:destroy) }
|
||||
it { is_expected.to have_many(:users_star_projects).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:environments).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:deployments).dependent(:destroy) }
|
||||
|
|
Loading…
Reference in a new issue