Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
0f1e3360
Commit
0f1e3360
authored
Sep 26, 2017
by
Simon Knox
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/2518-persisted-issue-boards-filter-be' into edit-board
parents
7d293b9f
b3c3b46b
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
369 additions
and
116 deletions
+369
-116
app/models/board_filter.rb
app/models/board_filter.rb
+21
-0
app/models/board_filter_label.rb
app/models/board_filter_label.rb
+8
-0
app/models/board_filter_label_spec.rb
app/models/board_filter_label_spec.rb
+16
-0
app/models/license.rb
app/models/license.rb
+134
-50
app/models/namespace.rb
app/models/namespace.rb
+2
-2
app/models/project.rb
app/models/project.rb
+2
-2
app/services/boards/update_service.rb
app/services/boards/update_service.rb
+1
-1
changelogs/unreleased-ee/2518-persisted-issue-boards-filter-be.yml
...s/unreleased-ee/2518-persisted-issue-boards-filter-be.yml
+5
-0
db/migrate/20170921154104_create_board_filters_table.rb
db/migrate/20170921154104_create_board_filters_table.rb
+27
-0
db/migrate/20170921195938_generate_board_filters.rb
db/migrate/20170921195938_generate_board_filters.rb
+19
-0
db/migrate/20170921203824_create_board_filter_labels.rb
db/migrate/20170921203824_create_board_filter_labels.rb
+23
-0
db/schema.rb
db/schema.rb
+30
-1
ee/app/helpers/ee/boards_helper.rb
ee/app/helpers/ee/boards_helper.rb
+1
-1
ee/app/models/ee/board.rb
ee/app/models/ee/board.rb
+2
-11
ee/app/views/shared/promotions/_promote_issue_board.html.haml
...pp/views/shared/promotions/_promote_issue_board.html.haml
+1
-1
lib/api/entities.rb
lib/api/entities.rb
+1
-1
spec/ee/spec/models/ee/board_spec.rb
spec/ee/spec/models/ee/board_spec.rb
+0
-37
spec/factories/board_filter_labels.rb
spec/factories/board_filter_labels.rb
+6
-0
spec/factories/board_filters.rb
spec/factories/board_filters.rb
+8
-0
spec/features/boards/board_with_milestone_spec.rb
spec/features/boards/board_with_milestone_spec.rb
+2
-2
spec/models/board_filter_spec.rb
spec/models/board_filter_spec.rb
+53
-0
spec/requests/api/boards_spec.rb
spec/requests/api/boards_spec.rb
+5
-5
spec/services/boards/update_service_spec.rb
spec/services/boards/update_service_spec.rb
+2
-2
No files found.
app/models/board_filter.rb
0 → 100644
View file @
0f1e3360
class
BoardFilter
<
ActiveRecord
::
Base
belongs_to
:board
belongs_to
:milestone
belongs_to
:author
,
class_name:
'User'
belongs_to
:assignee
,
class_name:
'User'
has_many
:board_filter_labels
has_many
:labels
,
through: :board_filter_labels
validates
:board
,
presence:
true
def
milestone
return
nil
unless
board
.
parent
.
feature_available?
(
:scoped_issue_board
)
if
milestone_id
==
::
Milestone
::
Upcoming
.
id
::
Milestone
::
Upcoming
else
super
end
end
end
app/models/board_filter_label.rb
0 → 100644
View file @
0f1e3360
class
BoardFilterLabel
<
ActiveRecord
::
Base
belongs_to
:board_filter
belongs_to
:label
validates
:board_filter
,
presence:
true
validates
:label
,
presence:
true
validates
:board_filter
,
uniqueness:
{
scope: :label_id
}
end
\ No newline at end of file
app/models/board_filter_label_spec.rb
0 → 100644
View file @
0f1e3360
require
'spec_helper'
describe
BoardFilterLabel
,
type: :model
do
describe
'validations'
do
subject
{
create
(
:board_filter_label
)
}
it
{
is_expected
.
to
validate_presence_of
(
:board_filter
)
}
it
{
is_expected
.
to
validate_presence_of
(
:label
)
}
it
{
is_expected
.
to
validate_uniqueness_of
(
:board_filter
).
scoped_to
(
:label_id
)
}
end
describe
'associations'
do
it
{
is_expected
.
to
belong_to
(
:board_filter
)
}
it
{
is_expected
.
to
belong_to
(
:label
)
}
end
end
\ No newline at end of file
app/models/license.rb
View file @
0f1e3360
class
License
<
ActiveRecord
::
Base
include
ActionView
::
Helpers
::
NumberHelper
ADMIN_AUDIT_LOG_FEATURE
=
'GitLab_AdminAuditLog'
.
freeze
AUDIT_EVENTS_FEATURE
=
'GitLab_AuditEvents'
.
freeze
AUDITOR_USER_FEATURE
=
'GitLab_Auditor_User'
.
freeze
BURNDOWN_CHARTS_FEATURE
=
'GitLab_BurndownCharts'
.
freeze
CONTRIBUTION_ANALYTICS_FEATURE
=
'GitLab_ContributionAnalytics'
.
freeze
CROSS_PROJECT_PIPELINES_FEATURE
=
'GitLab_CrossProjectPipelines'
.
freeze
DB_LOAD_BALANCING_FEATURE
=
'GitLab_DbLoadBalancing'
.
freeze
DEPLOY_BOARD_FEATURE
=
'GitLab_DeployBoard'
.
freeze
ELASTIC_SEARCH_FEATURE
=
'GitLab_ElasticSearch'
.
freeze
EXPORT_ISSUES_FEATURE
=
'GitLab_ExportIssues'
.
freeze
FAST_FORWARD_MERGE_FEATURE
=
'GitLab_FastForwardMerge'
.
freeze
FILE_LOCKS_FEATURE
=
'GitLab_FileLocks'
.
freeze
GEO_FEATURE
=
'GitLab_Geo'
.
freeze
GROUP_WEBHOOKS_FEATURE
=
'GitLab_GroupWebhooks'
.
freeze
ISSUABLE_DEFAULT_TEMPLATES_FEATURE
=
'GitLab_IssuableDefaultTemplates'
.
freeze
ISSUE_BOARD_FOCUS_MODE_FEATURE
=
'GitLab_IssueBoardFocusMode'
.
freeze
SCOPED_ISSUE_BOARD_FEATURE
=
'GitLab_ScopedIssueBoard'
.
freeze
GROUP_ISSUE_BOARDS_FEATURE
=
'GitLab_GroupIssueBoards'
.
freeze
ISSUE_WEIGHTS_FEATURE
=
'GitLab_IssueWeights'
.
freeze
JENKINS_INTEGRATION_FEATURE
=
'GitLab_JenkinsIntegration'
.
freeze
JIRA_DEV_PANEL_INTEGRATION_FEATURE
=
'GitLab_JiraDevelopmentPanelIntegration'
.
freeze
LDAP_EXTRAS_FEATURE
=
'GitLab_LdapExtras'
.
freeze
MERGE_REQUEST_APPROVERS_FEATURE
=
'GitLab_MergeRequestApprovers'
.
freeze
MERGE_REQUEST_REBASE_FEATURE
=
'GitLab_MergeRequestRebase'
.
freeze
MERGE_REQUEST_SQUASH_FEATURE
=
'GitLab_MergeRequestSquash'
.
freeze
MULTIPLE_ISSUE_ASSIGNEES_FEATURE
=
'GitLab_MultipleIssueAssignees'
.
freeze
MULTIPLE_ISSUE_BOARDS_FEATURE
=
'GitLab_MultipleIssueBoards'
.
freeze
OBJECT_STORAGE_FEATURE
=
'GitLab_ObjectStorage'
.
freeze
PROTECTED_REFS_FOR_USERS_FEATURE
=
'GitLab_RefPermissionsForUsers'
.
freeze
PUSH_RULES_FEATURE
=
'GitLab_PushRules'
.
freeze
RELATED_ISSUES_FEATURE
=
'GitLab_RelatedIssues'
.
freeze
REPOSITORY_MIRRORS_FEATURE
=
'GitLab_RepositoryMirrors'
.
freeze
REPOSITORY_SIZE_LIMIT_FEATURE
=
'GitLab_RepositorySizeLimit'
.
freeze
SERVICE_DESK_FEATURE
=
'GitLab_ServiceDesk'
.
freeze
VARIABLE_ENVIRONMENT_SCOPE_FEATURE
=
'GitLab_VariableEnvironmentScope'
.
freeze
FEATURE_CODES
=
{
admin_audit_log:
ADMIN_AUDIT_LOG_FEATURE
,
auditor_user:
AUDITOR_USER_FEATURE
,
db_load_balancing:
DB_LOAD_BALANCING_FEATURE
,
elastic_search:
ELASTIC_SEARCH_FEATURE
,
geo:
GEO_FEATURE
,
ldap_extras:
LDAP_EXTRAS_FEATURE
,
object_storage:
OBJECT_STORAGE_FEATURE
,
related_issues:
RELATED_ISSUES_FEATURE
,
repository_size_limit:
REPOSITORY_SIZE_LIMIT_FEATURE
,
service_desk:
SERVICE_DESK_FEATURE
,
variable_environment_scope:
VARIABLE_ENVIRONMENT_SCOPE_FEATURE
,
# Features that make sense to Namespace:
audit_events:
AUDIT_EVENTS_FEATURE
,
burndown_charts:
BURNDOWN_CHARTS_FEATURE
,
contribution_analytics:
CONTRIBUTION_ANALYTICS_FEATURE
,
cross_project_pipelines:
CROSS_PROJECT_PIPELINES_FEATURE
,
deploy_board:
DEPLOY_BOARD_FEATURE
,
export_issues:
EXPORT_ISSUES_FEATURE
,
fast_forward_merge:
FAST_FORWARD_MERGE_FEATURE
,
file_locks:
FILE_LOCKS_FEATURE
,
group_webhooks:
GROUP_WEBHOOKS_FEATURE
,
issuable_default_templates:
ISSUABLE_DEFAULT_TEMPLATES_FEATURE
,
issue_board_focus_mode:
ISSUE_BOARD_FOCUS_MODE_FEATURE
,
scoped_issue_board:
SCOPED_ISSUE_BOARD_FEATURE
,
group_issue_boards:
GROUP_ISSUE_BOARDS_FEATURE
,
issue_weights:
ISSUE_WEIGHTS_FEATURE
,
jenkins_integration:
JENKINS_INTEGRATION_FEATURE
,
jira_dev_panel_integration:
JIRA_DEV_PANEL_INTEGRATION_FEATURE
,
merge_request_approvers:
MERGE_REQUEST_APPROVERS_FEATURE
,
merge_request_rebase:
MERGE_REQUEST_REBASE_FEATURE
,
merge_request_squash:
MERGE_REQUEST_SQUASH_FEATURE
,
multiple_issue_assignees:
MULTIPLE_ISSUE_ASSIGNEES_FEATURE
,
multiple_issue_boards:
MULTIPLE_ISSUE_BOARDS_FEATURE
,
protected_refs_for_users:
PROTECTED_REFS_FOR_USERS_FEATURE
,
push_rules:
PUSH_RULES_FEATURE
,
repository_mirrors:
REPOSITORY_MIRRORS_FEATURE
}.
freeze
STARTER_PLAN
=
'starter'
.
freeze
PREMIUM_PLAN
=
'premium'
.
freeze
ULTIMATE_PLAN
=
'ultimate'
.
freeze
EARLY_ADOPTER_PLAN
=
'early_adopter'
.
freeze
EES_FEATURES
=
%i
[
audit_events
burndown_charts
contribution_analytics
elastic_search
export_issues
fast_forward_merge
group_webhooks
issuable_default_templates
issue_board_focus_mode
issue_board_milestone
issue_weights
jenkins_integration
ldap_extras
merge_request_approvers
merge_request_rebase
merge_request_squash
multiple_issue_assignees
multiple_issue_boards
push_rules
protected_refs_for_users
related_issues
repository_mirrors
repository_size_limit
EES_FEATURES
=
[
{
AUDIT_EVENTS_FEATURE
=>
1
},
{
BURNDOWN_CHARTS_FEATURE
=>
1
},
{
CONTRIBUTION_ANALYTICS_FEATURE
=>
1
},
{
ELASTIC_SEARCH_FEATURE
=>
1
},
{
EXPORT_ISSUES_FEATURE
=>
1
},
{
FAST_FORWARD_MERGE_FEATURE
=>
1
},
{
GROUP_WEBHOOKS_FEATURE
=>
1
},
{
ISSUABLE_DEFAULT_TEMPLATES_FEATURE
=>
1
},
{
ISSUE_BOARD_FOCUS_MODE_FEATURE
=>
1
},
{
SCOPED_ISSUE_BOARD_FEATURE
=>
1
},
{
ISSUE_WEIGHTS_FEATURE
=>
1
},
{
JENKINS_INTEGRATION_FEATURE
=>
1
},
{
LDAP_EXTRAS_FEATURE
=>
1
},
{
MERGE_REQUEST_APPROVERS_FEATURE
=>
1
},
{
MERGE_REQUEST_REBASE_FEATURE
=>
1
},
{
MERGE_REQUEST_SQUASH_FEATURE
=>
1
},
{
MULTIPLE_ISSUE_ASSIGNEES_FEATURE
=>
1
},
{
MULTIPLE_ISSUE_BOARDS_FEATURE
=>
1
},
{
PUSH_RULES_FEATURE
=>
1
},
{
PROTECTED_REFS_FOR_USERS_FEATURE
=>
1
},
{
RELATED_ISSUES_FEATURE
=>
1
},
{
REPOSITORY_MIRRORS_FEATURE
=>
1
},
{
REPOSITORY_SIZE_LIMIT_FEATURE
=>
1
}
].
freeze
EEP_FEATURES
=
EES_FEATURES
+
%i[
...
...
@@ -55,32 +131,40 @@ class License < ActiveRecord::Base
# Obs.: Do not extend from other feature constants.
# Early adopters should not earn new features as they're
# introduced.
EARLY_ADOPTER_FEATURES
=
%i[
audit_events
burndown_charts
contribution_analytics
cross_project_pipelines
deploy_board
export_issues
fast_forward_merge
file_locks
group_webhooks
issuable_default_templates
issue_board_focus_mode
issue_board_milestone
issue_weights
jenkins_integration
merge_request_approvers
merge_request_rebase
merge_request_squash
multiple_issue_assignees
multiple_issue_boards
protected_refs_for_users
push_rules
related_issues
repository_mirrors
service_desk
variable_environment_scope
EARLY_ADOPTER_FEATURES
=
[
{
ADMIN_AUDIT_LOG_FEATURE
=>
1
},
{
AUDIT_EVENTS_FEATURE
=>
1
},
{
AUDITOR_USER_FEATURE
=>
1
},
{
BURNDOWN_CHARTS_FEATURE
=>
1
},
{
CONTRIBUTION_ANALYTICS_FEATURE
=>
1
},
{
CROSS_PROJECT_PIPELINES_FEATURE
=>
1
},
{
DB_LOAD_BALANCING_FEATURE
=>
1
},
{
DEPLOY_BOARD_FEATURE
=>
1
},
{
ELASTIC_SEARCH_FEATURE
=>
1
},
{
EXPORT_ISSUES_FEATURE
=>
1
},
{
FAST_FORWARD_MERGE_FEATURE
=>
1
},
{
FILE_LOCKS_FEATURE
=>
1
},
{
GEO_FEATURE
=>
1
},
{
GROUP_WEBHOOKS_FEATURE
=>
1
},
{
ISSUABLE_DEFAULT_TEMPLATES_FEATURE
=>
1
},
{
ISSUE_BOARD_FOCUS_MODE_FEATURE
=>
1
},
{
SCOPED_ISSUE_BOARD_FEATURE
=>
1
},
{
ISSUE_WEIGHTS_FEATURE
=>
1
},
{
JENKINS_INTEGRATION_FEATURE
=>
1
},
{
LDAP_EXTRAS_FEATURE
=>
1
},
{
MERGE_REQUEST_APPROVERS_FEATURE
=>
1
},
{
MERGE_REQUEST_REBASE_FEATURE
=>
1
},
{
MERGE_REQUEST_SQUASH_FEATURE
=>
1
},
{
MULTIPLE_ISSUE_ASSIGNEES_FEATURE
=>
1
},
{
MULTIPLE_ISSUE_BOARDS_FEATURE
=>
1
},
{
OBJECT_STORAGE_FEATURE
=>
1
},
{
PROTECTED_REFS_FOR_USERS_FEATURE
=>
1
},
{
PUSH_RULES_FEATURE
=>
1
},
{
RELATED_ISSUES_FEATURE
=>
1
},
{
REPOSITORY_MIRRORS_FEATURE
=>
1
},
{
REPOSITORY_SIZE_LIMIT_FEATURE
=>
1
},
{
SERVICE_DESK_FEATURE
=>
1
},
{
VARIABLE_ENVIRONMENT_SCOPE_FEATURE
=>
1
}
].
freeze
FEATURES_BY_PLAN
=
{
...
...
app/models/namespace.rb
View file @
0f1e3360
...
...
@@ -218,8 +218,8 @@ class Namespace < ActiveRecord::Base
feature_available?
(
:multiple_issue_boards
)
end
def
issue_board_milestone
_available?
(
user
=
nil
)
feature_available?
(
:
issue_board_milestone
)
def
scoped_issue_board
_available?
(
user
=
nil
)
feature_available?
(
:
scoped_issue_board
)
end
private
...
...
app/models/project.rb
View file @
0f1e3360
...
...
@@ -1532,8 +1532,8 @@ class Project < ActiveRecord::Base
feature_available?
(
:multiple_issue_boards
,
user
)
end
def
issue_board_milestone
_available?
(
user
=
nil
)
feature_available?
(
:
issue_board_milestone
,
user
)
def
scoped_issue_board
_available?
(
user
=
nil
)
feature_available?
(
:
scoped_issue_board
,
user
)
end
def
full_path_was
...
...
app/services/boards/update_service.rb
View file @
0f1e3360
module
Boards
class
UpdateService
<
Boards
::
BaseService
def
execute
(
board
)
params
.
delete
(
:milestone_id
)
unless
parent
.
feature_available?
(
:
issue_board_milestone
)
params
.
delete
(
:milestone_id
)
unless
parent
.
feature_available?
(
:
scoped_issue_board
)
board
.
update
(
params
)
end
...
...
changelogs/unreleased-ee/2518-persisted-issue-boards-filter-be.yml
0 → 100644
View file @
0f1e3360
---
title
:
Allow persisting board configuration in order to automatically filter issues
merge_request
:
author
:
type
:
added
db/migrate/20170921154104_create_board_filters_table.rb
0 → 100644
View file @
0f1e3360
class
CreateBoardFiltersTable
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
create_table
:board_filters
do
|
t
|
t
.
integer
:board_id
,
null:
false
,
index:
true
t
.
integer
:milestone_id
,
index:
true
t
.
integer
:weight
,
index:
true
t
.
integer
:author_id
,
index:
true
t
.
integer
:assignee_id
,
index:
true
end
add_concurrent_foreign_key
:board_filters
,
:boards
,
column: :board_id
,
on_delete: :cascade
add_concurrent_foreign_key
:board_filters
,
:milestones
,
column: :milestone_id
,
on_delete: :nullify
add_concurrent_foreign_key
:board_filters
,
:users
,
column: :author_id
,
on_delete: :nullify
add_concurrent_foreign_key
:board_filters
,
:users
,
column: :assignee_id
,
on_delete: :nullify
end
def
down
drop_table
:board_filters
end
end
db/migrate/20170921195938_generate_board_filters.rb
0 → 100644
View file @
0f1e3360
class
GenerateBoardFilters
<
ActiveRecord
::
Migration
DOWNTIME
=
false
def
up
# Sub-query executed on production
# https://gitlab.com/gitlab-com/infrastructure/issues/2839#note_41023984
execute
<<-
SQL
INSERT INTO board_filters(board_id, milestone_id)
SELECT id as board_id, milestone_id FROM boards
WHERE (boards.milestone_id IS NOT NULL);
SQL
end
def
down
execute
<<-
SQL
DELETE FROM board_filters;
SQL
end
end
db/migrate/20170921203824_create_board_filter_labels.rb
0 → 100644
View file @
0f1e3360
class
CreateBoardFilterLabels
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
create_table
:board_filter_labels
do
|
t
|
t
.
integer
:board_filter_id
,
null:
false
,
index:
true
t
.
integer
:label_id
,
null:
false
,
index:
true
end
add_index
:board_filter_labels
,
[
:board_filter_id
,
:label_id
],
unique:
true
add_concurrent_foreign_key
:board_filter_labels
,
:board_filters
,
column: :board_filter_id
,
on_delete: :cascade
add_concurrent_foreign_key
:board_filter_labels
,
:labels
,
column: :label_id
,
on_delete: :cascade
end
def
down
drop_table
:board_filter_labels
end
end
db/schema.rb
View file @
0f1e3360
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
201709
18223303
)
do
ActiveRecord
::
Schema
.
define
(
version:
201709
21203824
)
do
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
...
...
@@ -214,6 +214,29 @@ ActiveRecord::Schema.define(version: 20170918223303) do
add_index
"award_emoji"
,
[
"awardable_type"
,
"awardable_id"
],
name:
"index_award_emoji_on_awardable_type_and_awardable_id"
,
using: :btree
add_index
"award_emoji"
,
[
"user_id"
,
"name"
],
name:
"index_award_emoji_on_user_id_and_name"
,
using: :btree
create_table
"board_filter_labels"
,
force: :cascade
do
|
t
|
t
.
integer
"board_filter_id"
,
null:
false
t
.
integer
"label_id"
,
null:
false
end
add_index
"board_filter_labels"
,
[
"board_filter_id"
,
"label_id"
],
name:
"index_board_filter_labels_on_board_filter_id_and_label_id"
,
unique:
true
,
using: :btree
add_index
"board_filter_labels"
,
[
"board_filter_id"
],
name:
"index_board_filter_labels_on_board_filter_id"
,
using: :btree
add_index
"board_filter_labels"
,
[
"label_id"
],
name:
"index_board_filter_labels_on_label_id"
,
using: :btree
create_table
"board_filters"
,
force: :cascade
do
|
t
|
t
.
integer
"board_id"
,
null:
false
t
.
integer
"milestone_id"
t
.
integer
"weight"
t
.
integer
"author_id"
t
.
integer
"assignee_id"
end
add_index
"board_filters"
,
[
"assignee_id"
],
name:
"index_board_filters_on_assignee_id"
,
using: :btree
add_index
"board_filters"
,
[
"author_id"
],
name:
"index_board_filters_on_author_id"
,
using: :btree
add_index
"board_filters"
,
[
"board_id"
],
name:
"index_board_filters_on_board_id"
,
using: :btree
add_index
"board_filters"
,
[
"milestone_id"
],
name:
"index_board_filters_on_milestone_id"
,
using: :btree
add_index
"board_filters"
,
[
"weight"
],
name:
"index_board_filters_on_weight"
,
using: :btree
create_table
"boards"
,
force: :cascade
do
|
t
|
t
.
integer
"project_id"
t
.
datetime
"created_at"
,
null:
false
...
...
@@ -2046,6 +2069,12 @@ ActiveRecord::Schema.define(version: 20170918223303) do
add_foreign_key
"approvals"
,
"merge_requests"
,
name:
"fk_310d714958"
,
on_delete: :cascade
add_foreign_key
"approver_groups"
,
"namespaces"
,
column:
"group_id"
,
on_delete: :cascade
add_foreign_key
"board_filter_labels"
,
"board_filters"
,
name:
"fk_ebc90d2f1a"
,
on_delete: :cascade
add_foreign_key
"board_filter_labels"
,
"labels"
,
name:
"fk_91e18fdcee"
,
on_delete: :cascade
add_foreign_key
"board_filters"
,
"boards"
,
name:
"fk_87e919b0eb"
,
on_delete: :cascade
add_foreign_key
"board_filters"
,
"milestones"
,
name:
"fk_37d28eeebc"
,
on_delete: :nullify
add_foreign_key
"board_filters"
,
"users"
,
column:
"assignee_id"
,
name:
"fk_e7893dfa6e"
,
on_delete: :nullify
add_foreign_key
"board_filters"
,
"users"
,
column:
"author_id"
,
name:
"fk_b341da4d2b"
,
on_delete: :nullify
add_foreign_key
"boards"
,
"namespaces"
,
column:
"group_id"
,
name:
"fk_1e9a074a35"
,
on_delete: :cascade
add_foreign_key
"boards"
,
"projects"
,
name:
"fk_f15266b5f9"
,
on_delete: :cascade
add_foreign_key
"chat_teams"
,
"namespaces"
,
on_delete: :cascade
...
...
ee/app/helpers/ee/boards_helper.rb
View file @
0f1e3360
...
...
@@ -8,7 +8,7 @@ module EE
data
=
{
board_milestone_title:
board
&
.
milestone
&
.
title
,
focus_mode_available:
parent
.
feature_available?
(
:issue_board_focus_mode
).
to_s
,
show_promotion:
(
@project
&&
show_promotions?
&&
(
!
@project
.
feature_available?
(
:multiple_issue_boards
)
||
!
@project
.
feature_available?
(
:
issue_board_milestone
)
||
!
@project
.
feature_available?
(
:issue_board_focus_mode
))).
to_s
show_promotion:
(
@project
&&
show_promotions?
&&
(
!
@project
.
feature_available?
(
:multiple_issue_boards
)
||
!
@project
.
feature_available?
(
:
scoped_issue_board
)
||
!
@project
.
feature_available?
(
:issue_board_focus_mode
))).
to_s
}
...
...
ee/app/models/ee/board.rb
View file @
0f1e3360
...
...
@@ -3,7 +3,8 @@ module EE
extend
ActiveSupport
::
Concern
prepended
do
belongs_to
:milestone
has_one
:board_filter
belongs_to
:group
validates
:name
,
presence:
true
...
...
@@ -14,16 +15,6 @@ module EE
!
group
end
def
milestone
return
nil
unless
parent
.
feature_available?
(
:issue_board_milestone
)
if
milestone_id
==
::
Milestone
::
Upcoming
.
id
::
Milestone
::
Upcoming
else
super
end
end
def
parent
@parent
||=
group
||
project
end
...
...
ee/app/views/shared/promotions/_promote_issue_board.html.haml
View file @
0f1e3360
...
...
@@ -12,7 +12,7 @@
-
unless
@project
.
feature_available?
(
:multiple_issue_boards
)
%li
=
link_to
_
(
'Multiple issue boards'
),
help_page_path
(
'user/project/issue_board.html'
,
anchor
:'use-cases-for-multiple-issue-boards'
),
target:
'_blank'
-
unless
@project
.
feature_available?
(
:
issue_board_milestone
)
-
unless
@project
.
feature_available?
(
:
scoped_issue_board
)
%li
=
link_to
_
(
'Issue boards with milestones'
),
help_page_path
(
'user/project/issue_board.html'
,
anchor
:'board-with-a-milestone'
),
target:
'_blank'
-
unless
@project
.
feature_available?
(
:issue_board_focus_mode
)
...
...
lib/api/entities.rb
View file @
0f1e3360
...
...
@@ -796,7 +796,7 @@ module API
expose
:name
expose
:project
,
using:
Entities
::
BasicProjectDetails
expose
:milestone
,
if:
->
(
board
,
_
)
{
board
.
project
.
feature_available?
(
:
issue_board_milestone
)
}
if:
->
(
board
,
_
)
{
board
.
project
.
feature_available?
(
:
scoped_issue_board
)
}
expose
:lists
,
using:
Entities
::
List
do
|
board
|
board
.
lists
.
destroyable
end
...
...
spec/ee/spec/models/ee/board_spec.rb
View file @
0f1e3360
...
...
@@ -16,41 +16,4 @@ describe Board do
it
{
is_expected
.
not_to
validate_presence_of
(
:group
)
}
end
end
describe
'milestone'
do
subject
(
:board
)
{
build
(
:board
)
}
context
'when the feature is available'
do
before
do
stub_licensed_features
(
issue_board_milestone:
true
)
end
it
'returns Milestone::Upcoming for upcoming milestone id'
do
board
.
milestone_id
=
Milestone
::
Upcoming
.
id
expect
(
board
.
milestone
).
to
eq
Milestone
::
Upcoming
end
it
'returns milestone for valid milestone id'
do
milestone
=
create
(
:milestone
)
board
.
milestone_id
=
milestone
.
id
expect
(
board
.
milestone
).
to
eq
milestone
end
it
'returns nil for invalid milestone id'
do
board
.
milestone_id
=
-
1
expect
(
board
.
milestone
).
to
be_nil
end
end
it
'returns nil when the feature is not available'
do
stub_licensed_features
(
issue_board_milestone:
false
)
milestone
=
create
(
:milestone
)
board
.
milestone_id
=
milestone
.
id
expect
(
board
.
milestone
).
to
be_nil
end
end
end
spec/factories/board_filter_labels.rb
0 → 100644
View file @
0f1e3360
FactoryGirl
.
define
do
factory
:board_filter_label
do
association
:board_filter
association
:label
end
end
spec/factories/board_filters.rb
0 → 100644
View file @
0f1e3360
FactoryGirl
.
define
do
factory
:board_filter
do
association
:board
association
:milestone
association
:author
,
factory: :user
association
:assignee
,
factory: :user
end
end
spec/features/boards/board_with_milestone_spec.rb
View file @
0f1e3360
...
...
@@ -17,7 +17,7 @@ describe 'Board with milestone', :js do
context
'with the feature enabled'
do
before
do
stub_licensed_features
(
issue_board_milestone
:
true
)
stub_licensed_features
(
scoped_issue_board
:
true
)
end
context
'new board'
do
...
...
@@ -173,7 +173,7 @@ describe 'Board with milestone', :js do
context
'with the feature disabled'
do
before
do
stub_licensed_features
(
issue_board_milestone
:
false
)
stub_licensed_features
(
scoped_issue_board
:
false
)
visit
project_boards_path
(
project
)
end
...
...
spec/models/board_filter_spec.rb
0 → 100644
View file @
0f1e3360
require
'spec_helper'
describe
BoardFilter
,
type: :model
do
describe
'validations'
do
it
{
is_expected
.
to
validate_presence_of
(
:board
)
}
end
describe
'associations'
do
it
{
is_expected
.
to
belong_to
(
:board
)
}
it
{
is_expected
.
to
belong_to
(
:milestone
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
belong_to
(
:assignee
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
have_many
(
:board_filter_labels
)
}
it
{
is_expected
.
to
have_many
(
:labels
).
through
(
:board_filter_labels
)
}
end
describe
'milestone'
do
subject
(
:board_filter
)
{
build
(
:board_filter
)
}
context
'when the feature is available'
do
before
do
stub_licensed_features
(
scoped_issue_board:
true
)
end
it
'returns Milestone::Upcoming for upcoming milestone id'
do
board_filter
.
milestone_id
=
Milestone
::
Upcoming
.
id
expect
(
board_filter
.
milestone
).
to
eq
Milestone
::
Upcoming
end
it
'returns milestone for valid milestone id'
do
milestone
=
create
(
:milestone
)
board_filter
.
milestone_id
=
milestone
.
id
expect
(
board_filter
.
milestone
).
to
eq
milestone
end
it
'returns nil for invalid milestone id'
do
board_filter
.
milestone_id
=
-
1
expect
(
board_filter
.
milestone
).
to
be_nil
end
end
it
'returns nil when the feature is not available'
do
stub_licensed_features
(
scoped_issue_board:
false
)
milestone
=
create
(
:milestone
)
board_filter
.
milestone_id
=
milestone
.
id
expect
(
board_filter
.
milestone
).
to
be_nil
end
end
end
spec/requests/api/boards_spec.rb
View file @
0f1e3360
...
...
@@ -60,17 +60,17 @@ describe API::Boards do
end
end
context
'with the
issue_board_milestone
-feature available'
do
it
'returns the milestone when the `
issue_board_milestone
`-feature is enabled'
do
stub_licensed_features
(
issue_board_milestone
:
true
)
context
'with the
scoped_issue_board
-feature available'
do
it
'returns the milestone when the `
scoped_issue_board
`-feature is enabled'
do
stub_licensed_features
(
scoped_issue_board
:
true
)
get
api
(
base_url
,
user
)
expect
(
json_response
.
first
[
"milestone"
]).
not_to
be_nil
end
it
'hides the milestone when the `
issue_board_milestone
`-feature is disabled'
do
stub_licensed_features
(
issue_board_milestone
:
false
)
it
'hides the milestone when the `
scoped_issue_board
`-feature is disabled'
do
stub_licensed_features
(
scoped_issue_board
:
false
)
get
api
(
base_url
,
user
)
...
...
spec/services/boards/update_service_spec.rb
View file @
0f1e3360
...
...
@@ -26,7 +26,7 @@ describe Boards::UpdateService do
end
it
'udpates the milestone with issue board milestones enabled'
do
stub_licensed_features
(
issue_board_milestone
:
true
)
stub_licensed_features
(
scoped_issue_board
:
true
)
milestone
=
create
(
:milestone
,
project:
project
)
service
=
described_class
.
new
(
project
,
double
,
milestone_id:
milestone
.
id
)
...
...
@@ -36,7 +36,7 @@ describe Boards::UpdateService do
end
it
'udpates the milestone with the issue board milestones feature enabled'
do
stub_licensed_features
(
issue_board_milestone
:
false
)
stub_licensed_features
(
scoped_issue_board
:
false
)
milestone
=
create
(
:milestone
,
project:
project
)
service
=
described_class
.
new
(
project
,
double
,
milestone_id:
milestone
.
id
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment