-
Notifications
You must be signed in to change notification settings - Fork 437
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12185 from danidoni/new-watchlist-implementation
Implement the new watchlist feature
- Loading branch information
Showing
21 changed files
with
509 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
src/api/app/assets/stylesheets/webui/new_watchlist/watchlist.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.color-inverted { | ||
-webkit-filter: invert(100%); /* safari 6.0 - 9.0 */ | ||
filter: invert(100%); | ||
} |
18 changes: 18 additions & 0 deletions
18
src/api/app/components/watched_items_list_component.html.haml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
%h5.mt-2.text-light= list_title | ||
- if @items.any? | ||
- @items.each do |item| | ||
- case @class_name | ||
- when 'Package' | ||
= link_to(package_show_path(item.project, item), class: 'text-word-break-all') do | ||
%i.fas.fa-archive.mr-1 | ||
#{item.project}/#{item} | ||
- when 'Project' | ||
= link_to(project_show_path(item), class: 'text-word-break-all') do | ||
%i.fas.fa-cubes.mr-1 | ||
#{item} | ||
- when 'BsRequest' | ||
= link_to(request_show_path(number: item.number), class: 'text-word-break-all') do | ||
= image_tag('icons/request-icon.svg', height: 18, class: 'mr-1 color-inverted') | ||
Request ##{item.number} | ||
- else | ||
%p.text-muted= empty_list_text |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
class WatchedItemsListComponent < ApplicationComponent | ||
LIST_TITLE = { | ||
'Package' => 'Packages you are watching', | ||
'Project' => 'Projects you are watching', | ||
'BsRequest' => 'Requests you are watching' | ||
}.freeze | ||
|
||
EMPTY_LIST_TEXTS = { | ||
'Package' => 'There are no packages in the watchlist yet.', | ||
'Project' => 'There are no projects in the watchlist yet.', | ||
'BsRequest' => 'There are no requests in the watchlist yet.' | ||
}.freeze | ||
|
||
def initialize(items:, class_name:) | ||
super | ||
|
||
@items = items | ||
@class_name = class_name | ||
end | ||
|
||
private | ||
|
||
def list_title | ||
LIST_TITLE[@class_name] | ||
end | ||
|
||
def empty_list_text | ||
EMPTY_LIST_TEXTS[@class_name] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.navbar-collapse.watchlist-collapse.navbar-dark | ||
.navbar-nav.mb-4 | ||
.nav.justify-content-end.py-2 | ||
%button.navbar-toggler{ type: 'button', data: { toggle: 'watchlist' }, aria: { expanded: 'false', label: 'Toggle navigation' } } | ||
%i.fas.fa-times | ||
|
||
- if @object_to_be_watched | ||
.nav-item.pb-2.mb-4.border-bottom.border-gray-500 | ||
= link_to(toggle_watchable_path, method: :put, class: 'nav-link') do | ||
- if object_to_be_watched_in_watchlist? | ||
%p.mb-0.text-light | ||
%i.fas.fa-times-circle | ||
%span= remove_from_watchlist_text | ||
- else | ||
%p.mb-0.text-light | ||
%i.fas.fa-plus-circle | ||
%span= add_to_watchlist_text | ||
|
||
= render WatchedItemsListComponent.new(items: projects, class_name: 'Project') | ||
= render WatchedItemsListComponent.new(items: packages, class_name: 'Package') | ||
= render WatchedItemsListComponent.new(items: bs_requests, class_name: 'BsRequest') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
class WatchlistComponent < ApplicationComponent | ||
REMOVE_FROM_WATCHLIST_TEXT = { | ||
'Package' => 'Remove this package from Watchlist', | ||
'Project' => 'Remove this project from Watchlist', | ||
'BsRequest' => 'Remove this request from Watchlist' | ||
}.freeze | ||
|
||
ADD_TO_WATCHLIST_TEXT = { | ||
'Package' => 'Watch this package', | ||
'Project' => 'Watch this project', | ||
'BsRequest' => 'Watch this request' | ||
}.freeze | ||
|
||
def initialize(user:, project: nil, package: nil, bs_request: nil) | ||
super | ||
|
||
@user = user | ||
# NOTE: the order of the array is important, when project and packge are both present we ensure it takes package. | ||
@object_to_be_watched = [bs_request, package, project].compact.first | ||
end | ||
|
||
private | ||
|
||
def object_to_be_watched_in_watchlist? | ||
!!@user.watched_items.includes(:watchable).find_by(watchable: @object_to_be_watched) | ||
end | ||
|
||
def add_to_watchlist_text | ||
ADD_TO_WATCHLIST_TEXT[@object_to_be_watched.class.name] | ||
end | ||
|
||
def remove_from_watchlist_text | ||
REMOVE_FROM_WATCHLIST_TEXT[@object_to_be_watched.class.name] | ||
end | ||
|
||
def toggle_watchable_path | ||
case @object_to_be_watched | ||
when Package | ||
toggle_package_watched_items_path(project: @object_to_be_watched.project.name, package: @object_to_be_watched.name) | ||
when Project | ||
toggle_project_watched_items_path(project: @object_to_be_watched.name) | ||
when BsRequest | ||
toggle_request_watched_items_path(number: @object_to_be_watched.number) | ||
end | ||
end | ||
|
||
def projects | ||
@projects ||= Project.joins(:watched_items).where(watched_items: { user: @user }) | ||
end | ||
|
||
def packages | ||
@packages ||= Package.joins(:watched_items).where(watched_items: { user: @user }) | ||
end | ||
|
||
def bs_requests | ||
@bs_requests ||= BsRequest.joins(:watched_items).where(watched_items: { user: @user }) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
class Webui::WatchedItemsController < Webui::WebuiController | ||
before_action :require_login | ||
before_action :check_user_belongs_feature_flag | ||
before_action :set_item | ||
|
||
FLASH_PER_WATCHABLE_TYPE = { | ||
Package => 'package', | ||
Project => 'project', | ||
BsRequest => 'request' | ||
}.freeze | ||
|
||
def toggle | ||
watched_item = User.session!.watched_items.find_by(watchable: @item) | ||
|
||
if watched_item | ||
watched_item.destroy | ||
flash[:success] = "Removed #{FLASH_PER_WATCHABLE_TYPE[@item.class]} from the watchlist" | ||
else | ||
User.session!.watched_items.create(watchable: @item) | ||
flash[:success] = "Added #{FLASH_PER_WATCHABLE_TYPE[@item.class]} to the watchlist" | ||
end | ||
|
||
redirect_back(fallback_location: root_path) | ||
end | ||
|
||
private | ||
|
||
def set_item | ||
@item = if params[:package] | ||
Package.find_by_project_and_name(params[:project], params[:package]) | ||
elsif params[:project] | ||
Project.find_by(name: params[:project]) | ||
elsif params[:number] | ||
BsRequest.find_by(number: params[:number]) | ||
end | ||
end | ||
|
||
def check_user_belongs_feature_flag | ||
raise NotFoundError unless Flipper.enabled?(:new_watchlist, User.session) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
class WatchedItem < ApplicationRecord | ||
belongs_to :watchable, polymorphic: true | ||
belongs_to :user | ||
|
||
validates :watchable_id, uniqueness: { scope: [:watchable_type, :user_id] } | ||
end | ||
|
||
# == Schema Information | ||
# | ||
# Table name: watched_items | ||
# | ||
# id :integer not null, primary key | ||
# watchable_type :string(255) not null, indexed => [watchable_id, user_id], indexed => [watchable_id] | ||
# created_at :datetime not null | ||
# updated_at :datetime not null | ||
# user_id :integer indexed => [watchable_type, watchable_id], indexed | ||
# watchable_id :integer not null, indexed => [watchable_type, user_id], indexed => [watchable_type] | ||
# | ||
# Indexes | ||
# | ||
# index_watched_items_on_type_id_and_user_id (watchable_type,watchable_id,user_id) UNIQUE | ||
# index_watched_items_on_user_id (user_id) | ||
# index_watched_items_on_watchable (watchable_type,watchable_id) | ||
# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class CreateWatchedItems < ActiveRecord::Migration[6.1] | ||
def change | ||
create_table :watched_items, id: :integer do |t| | ||
t.integer :watchable_id, null: false | ||
t.string :watchable_type, null: false | ||
t.integer :user_id, index: true | ||
t.timestamps | ||
end | ||
|
||
add_index :watched_items, [:watchable_type, :watchable_id], name: 'index_watched_items_on_watchable' | ||
add_index :watched_items, [:watchable_type, :watchable_id, :user_id], name: 'index_watched_items_on_type_id_and_user_id', unique: true | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.