Commit 1bbc8858 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch '240947-create-table-for-persisting-swimlane-collapsed-status' into 'master'

Create table for persisting epic swimlane collapsed status

Closes #240947

See merge request gitlab-org/gitlab!40360
parents 829b9f5c 803ae53b
---
title: Add table for storing user settings for board epic swimlanes
merge_request: 40360
author:
type: added
# frozen_string_literal: true
class BoardsEpicUserPreferences < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
create_table :boards_epic_user_preferences do |t|
t.bigint :board_id, null: false
t.bigint :user_id, null: false
t.bigint :epic_id, null: false
t.boolean :collapsed, default: false, null: false
end
add_index :boards_epic_user_preferences, :board_id
add_index :boards_epic_user_preferences, :user_id
add_index :boards_epic_user_preferences, :epic_id
add_index :boards_epic_user_preferences, [:board_id, :user_id, :epic_id], unique: true, name: 'index_boards_epic_user_preferences_on_board_user_epic_unique'
end
def down
drop_table :boards_epic_user_preferences
end
end
# frozen_string_literal: true
class BoardsEpicUserPreferencesFkBoard < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
add_foreign_key :boards_epic_user_preferences, :boards, column: :board_id, on_delete: :cascade # rubocop: disable Migration/AddConcurrentForeignKey
end
end
def down
with_lock_retries do
remove_foreign_key :boards_epic_user_preferences, column: :board_id
end
end
end
# frozen_string_literal: true
class BoardsEpicUserPreferencesFkUser < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
add_foreign_key :boards_epic_user_preferences, :users, column: :user_id, on_delete: :cascade # rubocop: disable Migration/AddConcurrentForeignKey
end
end
def down
with_lock_retries do
remove_foreign_key :boards_epic_user_preferences, column: :user_id
end
end
end
# frozen_string_literal: true
class BoardsEpicUserPreferencesFkEpic < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
add_foreign_key :boards_epic_user_preferences, :epics, column: :epic_id, on_delete: :cascade # rubocop: disable Migration/AddConcurrentForeignKey
end
end
def down
with_lock_retries do
remove_foreign_key :boards_epic_user_preferences, column: :epic_id
end
end
end
1ee7ae93dde7099f78cd6218b5419a34b2cfebe196521bcbee1583e31f19ffda
\ No newline at end of file
26fe286e565f776f64ae8b6b0ad91ef1d3bf2195384f44f8b093a1b66ee0d05d
\ No newline at end of file
deb88efebc989a014b6ecaca4a91624d1b21f34c85cbf6d3460363f1b498b427
\ No newline at end of file
8fc437f09321cfe29262075009bce6f7b0047c2291df4a29bcc304c6dd54d27d
\ No newline at end of file
...@@ -9672,6 +9672,23 @@ CREATE TABLE public.boards ( ...@@ -9672,6 +9672,23 @@ CREATE TABLE public.boards (
hide_closed_list boolean DEFAULT false NOT NULL hide_closed_list boolean DEFAULT false NOT NULL
); );
CREATE TABLE public.boards_epic_user_preferences (
id bigint NOT NULL,
board_id bigint NOT NULL,
user_id bigint NOT NULL,
epic_id bigint NOT NULL,
collapsed boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE public.boards_epic_user_preferences_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.boards_epic_user_preferences_id_seq OWNED BY public.boards_epic_user_preferences.id;
CREATE SEQUENCE public.boards_id_seq CREATE SEQUENCE public.boards_id_seq
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
...@@ -16845,6 +16862,8 @@ ALTER TABLE ONLY public.board_user_preferences ALTER COLUMN id SET DEFAULT nextv ...@@ -16845,6 +16862,8 @@ ALTER TABLE ONLY public.board_user_preferences ALTER COLUMN id SET DEFAULT nextv
ALTER TABLE ONLY public.boards ALTER COLUMN id SET DEFAULT nextval('public.boards_id_seq'::regclass); ALTER TABLE ONLY public.boards ALTER COLUMN id SET DEFAULT nextval('public.boards_id_seq'::regclass);
ALTER TABLE ONLY public.boards_epic_user_preferences ALTER COLUMN id SET DEFAULT nextval('public.boards_epic_user_preferences_id_seq'::regclass);
ALTER TABLE ONLY public.broadcast_messages ALTER COLUMN id SET DEFAULT nextval('public.broadcast_messages_id_seq'::regclass); ALTER TABLE ONLY public.broadcast_messages ALTER COLUMN id SET DEFAULT nextval('public.broadcast_messages_id_seq'::regclass);
ALTER TABLE ONLY public.chat_names ALTER COLUMN id SET DEFAULT nextval('public.chat_names_id_seq'::regclass); ALTER TABLE ONLY public.chat_names ALTER COLUMN id SET DEFAULT nextval('public.chat_names_id_seq'::regclass);
...@@ -17774,6 +17793,9 @@ ALTER TABLE ONLY public.board_project_recent_visits ...@@ -17774,6 +17793,9 @@ ALTER TABLE ONLY public.board_project_recent_visits
ALTER TABLE ONLY public.board_user_preferences ALTER TABLE ONLY public.board_user_preferences
ADD CONSTRAINT board_user_preferences_pkey PRIMARY KEY (id); ADD CONSTRAINT board_user_preferences_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.boards_epic_user_preferences
ADD CONSTRAINT boards_epic_user_preferences_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.boards ALTER TABLE ONLY public.boards
ADD CONSTRAINT boards_pkey PRIMARY KEY (id); ADD CONSTRAINT boards_pkey PRIMARY KEY (id);
...@@ -19219,6 +19241,14 @@ CREATE INDEX index_board_user_preferences_on_user_id ON public.board_user_prefer ...@@ -19219,6 +19241,14 @@ CREATE INDEX index_board_user_preferences_on_user_id ON public.board_user_prefer
CREATE UNIQUE INDEX index_board_user_preferences_on_user_id_and_board_id ON public.board_user_preferences USING btree (user_id, board_id); CREATE UNIQUE INDEX index_board_user_preferences_on_user_id_and_board_id ON public.board_user_preferences USING btree (user_id, board_id);
CREATE INDEX index_boards_epic_user_preferences_on_board_id ON public.boards_epic_user_preferences USING btree (board_id);
CREATE UNIQUE INDEX index_boards_epic_user_preferences_on_board_user_epic_unique ON public.boards_epic_user_preferences USING btree (board_id, user_id, epic_id);
CREATE INDEX index_boards_epic_user_preferences_on_epic_id ON public.boards_epic_user_preferences USING btree (epic_id);
CREATE INDEX index_boards_epic_user_preferences_on_user_id ON public.boards_epic_user_preferences USING btree (user_id);
CREATE INDEX index_boards_on_group_id ON public.boards USING btree (group_id); CREATE INDEX index_boards_on_group_id ON public.boards USING btree (group_id);
CREATE INDEX index_boards_on_milestone_id ON public.boards USING btree (milestone_id); CREATE INDEX index_boards_on_milestone_id ON public.boards USING btree (milestone_id);
...@@ -22245,6 +22275,9 @@ ALTER TABLE ONLY public.group_custom_attributes ...@@ -22245,6 +22275,9 @@ ALTER TABLE ONLY public.group_custom_attributes
ALTER TABLE ONLY public.cluster_agents ALTER TABLE ONLY public.cluster_agents
ADD CONSTRAINT fk_rails_25e9fc2d5d FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_25e9fc2d5d FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.boards_epic_user_preferences
ADD CONSTRAINT fk_rails_268c57d62d FOREIGN KEY (board_id) REFERENCES public.boards(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.group_wiki_repositories ALTER TABLE ONLY public.group_wiki_repositories
ADD CONSTRAINT fk_rails_26f867598c FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_26f867598c FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
...@@ -22680,6 +22713,9 @@ ALTER TABLE ONLY public.x509_certificates ...@@ -22680,6 +22713,9 @@ ALTER TABLE ONLY public.x509_certificates
ALTER TABLE ONLY public.pages_domain_acme_orders ALTER TABLE ONLY public.pages_domain_acme_orders
ADD CONSTRAINT fk_rails_76581b1c16 FOREIGN KEY (pages_domain_id) REFERENCES public.pages_domains(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_76581b1c16 FOREIGN KEY (pages_domain_id) REFERENCES public.pages_domains(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.boards_epic_user_preferences
ADD CONSTRAINT fk_rails_76c4e9732d FOREIGN KEY (epic_id) REFERENCES public.epics(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.ci_subscriptions_projects ALTER TABLE ONLY public.ci_subscriptions_projects
ADD CONSTRAINT fk_rails_7871f9a97b FOREIGN KEY (upstream_project_id) REFERENCES public.projects(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_7871f9a97b FOREIGN KEY (upstream_project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
...@@ -22713,6 +22749,9 @@ ALTER TABLE ONLY public.approval_merge_request_rules_users ...@@ -22713,6 +22749,9 @@ ALTER TABLE ONLY public.approval_merge_request_rules_users
ALTER TABLE ONLY public.dast_site_profiles ALTER TABLE ONLY public.dast_site_profiles
ADD CONSTRAINT fk_rails_83e309d69e FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_83e309d69e FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.boards_epic_user_preferences
ADD CONSTRAINT fk_rails_851fe1510a FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.deployment_merge_requests ALTER TABLE ONLY public.deployment_merge_requests
ADD CONSTRAINT fk_rails_86a6d8bf12 FOREIGN KEY (merge_request_id) REFERENCES public.merge_requests(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_86a6d8bf12 FOREIGN KEY (merge_request_id) REFERENCES public.merge_requests(id) ON DELETE CASCADE;
......
# frozen_string_literal: true
module Boards
class EpicUserPreference < ApplicationRecord
self.table_name = 'boards_epic_user_preferences'
belongs_to :user, inverse_of: :boards_epic_user_preferences
belongs_to :board, inverse_of: :boards_epic_user_preferences
belongs_to :epic, inverse_of: :boards_epic_user_preferences
validates :user, uniqueness: { scope: [:board_id, :epic_id] }
end
end
...@@ -13,6 +13,7 @@ module EE ...@@ -13,6 +13,7 @@ module EE
has_many :board_labels has_many :board_labels
has_many :user_preferences, class_name: 'BoardUserPreference', inverse_of: :board has_many :user_preferences, class_name: 'BoardUserPreference', inverse_of: :board
has_many :boards_epic_user_preferences, class_name: 'Boards::EpicUserPreference', inverse_of: :board
# These can safely be changed to has_many when we support # These can safely be changed to has_many when we support
# multiple assignees on the board configuration. # multiple assignees on the board configuration.
......
...@@ -52,6 +52,7 @@ module EE ...@@ -52,6 +52,7 @@ module EE
has_many :epic_issues has_many :epic_issues
has_many :issues, through: :epic_issues has_many :issues, through: :epic_issues
has_many :user_mentions, class_name: "EpicUserMention", dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent has_many :user_mentions, class_name: "EpicUserMention", dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :boards_epic_user_preferences, class_name: 'Boards::EpicUserPreference', inverse_of: :epic
validates :group, presence: true validates :group, presence: true
validate :validate_parent, on: :create validate :validate_parent, on: :create
......
...@@ -39,6 +39,7 @@ module EE ...@@ -39,6 +39,7 @@ module EE
has_many :path_locks, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent has_many :path_locks, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent
has_many :vulnerability_feedback, foreign_key: :author_id, class_name: 'Vulnerabilities::Feedback' has_many :vulnerability_feedback, foreign_key: :author_id, class_name: 'Vulnerabilities::Feedback'
has_many :commented_vulnerability_feedback, foreign_key: :comment_author_id, class_name: 'Vulnerabilities::Feedback' has_many :commented_vulnerability_feedback, foreign_key: :comment_author_id, class_name: 'Vulnerabilities::Feedback'
has_many :boards_epic_user_preferences, class_name: 'Boards::EpicUserPreference', inverse_of: :user
has_many :approvals, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent has_many :approvals, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent
has_many :approvers, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent has_many :approvers, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent
......
# frozen_string_literal: true
FactoryBot.define do
factory :epic_user_preference, class: 'Boards::EpicUserPreference' do
board
user
epic
end
end
...@@ -14,6 +14,7 @@ RSpec.describe Board do ...@@ -14,6 +14,7 @@ RSpec.describe Board do
it { is_expected.to have_many(:board_labels) } it { is_expected.to have_many(:board_labels) }
it { is_expected.to have_many(:labels).through(:board_labels) } it { is_expected.to have_many(:labels).through(:board_labels) }
it { is_expected.to have_many(:user_preferences) } it { is_expected.to have_many(:user_preferences) }
it { is_expected.to have_many(:boards_epic_user_preferences).class_name('Boards::EpicUserPreference') }
end end
describe 'validations' do describe 'validations' do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Boards::EpicUserPreference do
subject { build(:epic_user_preference) }
describe 'associations' do
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:board) }
it { is_expected.to belong_to(:epic) }
end
describe 'validations' do
it { is_expected.to validate_uniqueness_of(:user).scoped_to([:board_id, :epic_id]) }
end
end
...@@ -16,7 +16,8 @@ RSpec.describe Epic do ...@@ -16,7 +16,8 @@ RSpec.describe Epic do
it { is_expected.to belong_to(:parent) } it { is_expected.to belong_to(:parent) }
it { is_expected.to have_many(:epic_issues) } it { is_expected.to have_many(:epic_issues) }
it { is_expected.to have_many(:children) } it { is_expected.to have_many(:children) }
it { is_expected.to have_many(:user_mentions).class_name("EpicUserMention") } it { is_expected.to have_many(:user_mentions).class_name('EpicUserMention') }
it { is_expected.to have_many(:boards_epic_user_preferences).class_name('Boards::EpicUserPreference') }
end end
describe 'scopes' do describe 'scopes' do
......
...@@ -26,6 +26,7 @@ RSpec.describe User do ...@@ -26,6 +26,7 @@ RSpec.describe User do
it { is_expected.to have_many(:users_security_dashboard_projects) } it { is_expected.to have_many(:users_security_dashboard_projects) }
it { is_expected.to have_many(:security_dashboard_projects) } it { is_expected.to have_many(:security_dashboard_projects) }
it { is_expected.to have_many(:board_preferences) } it { is_expected.to have_many(:board_preferences) }
it { is_expected.to have_many(:boards_epic_user_preferences).class_name('Boards::EpicUserPreference') }
end end
describe 'nested attributes' do describe 'nested attributes' do
......
...@@ -615,6 +615,7 @@ boards: ...@@ -615,6 +615,7 @@ boards:
- assignee - assignee
- labels - labels
- user_preferences - user_preferences
- boards_epic_user_preferences
lists: lists:
- user - user
- milestone - milestone
...@@ -677,6 +678,7 @@ epic: ...@@ -677,6 +678,7 @@ epic:
- resource_label_events - resource_label_events
- user_mentions - user_mentions
- note_authors - note_authors
- boards_epic_user_preferences
epic_issue: epic_issue:
- epic - epic
- issue - issue
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment