Skip to content

Commit e336916

Browse files
authored
Set current provider 75 (#96)
2 parents 5c7337d + d0ac74e commit e336916

File tree

10 files changed

+143
-48
lines changed

10 files changed

+143
-48
lines changed

app/controllers/application_controller.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,13 @@ class ApplicationController < ActionController::Base
22
include Authentication
33
# Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
44
allow_browser versions: :modern
5+
6+
def current_provider
7+
@current_provider ||= begin
8+
Current.user.providers.find(cookies.signed[:current_provider_id])
9+
rescue ActiveRecord::RecordNotFound
10+
Current.user.providers.first
11+
end
12+
end
13+
helper_method :current_provider
514
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class SettingsController < ApplicationController
2+
def provider
3+
provider = provider_scope.find(provider_params[:id])
4+
cookies.signed[:current_provider_id] = provider.id if provider
5+
redirect_to request.referer || root_path
6+
end
7+
8+
private
9+
10+
def provider_params
11+
params.expect(provider: :id)
12+
end
13+
14+
def provider_scope
15+
@provider_scope ||= if Current.user.is_admin?
16+
Provider.all
17+
else
18+
Current.user.providers
19+
end
20+
end
21+
end

app/controllers/topics_controller.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class TopicsController < ApplicationController
33

44
def index
55
@topics = scope.search_with_params(search_params)
6-
@providers = scope.map(&:provider).uniq.sort_by(&:name)
6+
@available_providers = other_available_providers
77
@languages = scope.map(&:language).uniq.sort_by(&:name)
88
end
99

@@ -45,16 +45,22 @@ def archive
4545

4646
private
4747

48+
def other_available_providers
49+
return [] unless Current.user.providers.any?
50+
51+
Current.user.providers.where.not(id: current_provider.id)
52+
end
53+
4854
def topic_params
4955
params.require(:topic).permit(:title, :description, :uid, :language_id, :provider_id, documents: [])
5056
end
5157

52-
helper_method :search_params
5358
def search_params
5459
return {} unless params[:search].present?
5560

5661
params.require(:search).permit(:query, :state, :provider_id, :language_id, :year, :month, :order)
5762
end
63+
helper_method :search_params
5864

5965
def set_topic
6066
@topic = Topic.find(params[:id])
@@ -63,8 +69,15 @@ def set_topic
6369
def scope
6470
@scope ||= if Current.user.is_admin?
6571
Topic.all
72+
elsif current_provider.present?
73+
current_provider.topics
6674
else
6775
Current.user.topics
6876
end.includes(:language, :provider)
6977
end
78+
79+
def topics_title
80+
current_provider.present? ? "#{current_provider.name}/topics" : "Topics"
81+
end
82+
helper_method :topics_title
7083
end

app/javascript/controllers/topics_controller.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import { Controller } from "@hotwired/stimulus"
22
import { useDebounce } from "stimulus-use"
33

44
export default class extends Controller {
5-
static targets = [ "form" ]
5+
static targets = [ "searchForm", "chooseForm" ]
66
static debounces = [ "search" ]
77

88
connect() {
99
useDebounce(this, { wait: 300 })
1010
}
1111

12-
search() {
13-
this.formTarget.requestSubmit()
12+
searchTopics() {
13+
this.searchFormTarget.requestSubmit()
14+
}
15+
16+
chooseProvider() {
17+
this.chooseFormTarget.requestSubmit()
1418
}
1519
}

app/models/provider.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Provider < ApplicationRecord
1818
has_many :regions, through: :branches
1919
has_many :contributors
2020
has_many :users, through: :contributors
21+
has_many :topics
2122

2223
validates :name, :provider_type, presence: true
2324
validates :name, uniqueness: true
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<%= form_for :provider , url: provider_settings_path, method: :put, data: { controller: "topics", topics_target: "chooseForm", turbo_frame: "topics", turbo_action: "advance" } do |f| %>
2+
<div class="form-body">
3+
<div class="row">
4+
<div class="col-md-6 col-12">
5+
<div class="form-group">
6+
<%= f.label :provider %>
7+
<%= f.select :id, options_from_collection_for_select(providers, :id, :name), { prompt: "Change provider" }, class: "form-select", data: { action: "change->topics#chooseProvider" } %>
8+
</div>
9+
</div>
10+
</div>
11+
</div>
12+
<% end %>

app/views/topics/_search.html.erb

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,43 @@
44
</div>
55
<div class="card-content">
66
<div class="card-body">
7-
<%= form_for :search, url: topics_path, method: :get, data: { controller: "topics", topics_target: "form", turbo_frame: "topic-list", turbo_action: "advance" } do |f| %>
7+
<%= form_for :search, url: topics_path, method: :get, data: { controller: "topics", topics_target: "searchForm", turbo_frame: "topic-list", turbo_action: "advance" } do |f| %>
88
<div class="form-body">
99
<div class="row">
10-
<div class="col-md-6 col-12">
10+
<div class="col-12">
1111
<div class="form-group">
12-
<%= f.label :provider %>
13-
<%= f.select :provider_id, options_from_collection_for_select(providers, :id, :name, params[:provider_id]), { prompt: "Select provider" }, class: "form-select", data: { action: "change->topics#search" } %>
12+
<%= f.label :query %>
13+
<%= f.text_field :query, value: params[:query], class: "form-control", data: { action: "input->topics#searchTopics" } %>
1414
</div>
1515
</div>
1616
<div class="col-md-6 col-12">
1717
<div class="form-group">
1818
<%= f.label :language %>
19-
<%= f.select :language_id, options_from_collection_for_select(languages, :id, :name, params[:provider_id]), { prompt: "Select language" }, class: "form-select", data: { action: "change->topics#search" } %>
20-
</div>
21-
</div>
22-
<div class="col-md-6 col-12">
23-
<div class="form-group">
24-
<%= f.label :query %>
25-
<%= f.text_field :query, value: params[:query], class: "form-control", data: { action: "input->topics#search" } %>
19+
<%= f.select :language_id, options_from_collection_for_select(languages, :id, :name, params[:provider_id]), { prompt: "Select language" }, class: "form-select", data: { action: "change->topics#searchTopics" } %>
2620
</div>
2721
</div>
2822
<div class="col-md-3 col-12">
2923
<div class="form-group">
3024
<%= f.label :year %>
31-
<%= f.select :year, options_for_select((Date.today.year-10..Date.today.year).to_a, params[:year]), { prompt: "Select year" }, class: "form-select", data: { action: "change->topics#search" } %>
25+
<%= f.select :year, options_for_select((Date.today.year-10..Date.today.year).to_a, params[:year]), { prompt: "Select year" }, class: "form-select", data: { action: "change->topics#searchTopics" } %>
3226
</div>
3327
</div>
3428
<div class="col-md-3 col-12">
3529
<div class="form-group">
3630
<%= f.label :month %>
37-
<%= f.select :month, options_for_select((1..12).to_a, params[:month]), { prompt: "Select month" }, class: "form-select", data: { action: "change->topics#search" } %>
31+
<%= f.select :month, options_for_select((1..12).to_a, params[:month]), { prompt: "Select month" }, class: "form-select", data: { action: "change->topics#searchTopics" } %>
3832
</div>
3933
</div>
4034
<div class="col-md-6 col-12">
4135
<div class="form-group">
4236
<%= f.label :state %>
43-
<%= f.select :state, options_for_select(Topic::STATES.index_with(&:itself), params[:state]), { prompt: "Select state" }, class: "form-select", data: { action: "change->topics#search" } %>
37+
<%= f.select :state, options_for_select(Topic::STATES.index_with(&:itself), params[:state]), { prompt: "Select state" }, class: "form-select", data: { action: "change->topics#searchTopics" } %>
4438
</div>
4539
</div>
4640
<div class="col-md-6 col-12">
4741
<div class="form-group">
4842
<%= f.label :order %>
49-
<%= f.select :order, options_for_select(Topic::SORTS.reverse.index_with(&:itself), params[:order]), {}, class: "form-select", data: { action: "change->topics#search" } %>
43+
<%= f.select :order, options_for_select(Topic::SORTS.reverse.index_with(&:itself), params[:order]), {}, class: "form-select", data: { action: "change->topics#searchTopics" } %>
5044
</div>
5145
</div>
5246
<div class="col-12 d-flex justify-content-end">

app/views/topics/index.html.erb

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,42 @@
44
<div class="row" id="table-striped">
55
<div class="col-12 cold-md-12">
66
<%= render "search", providers: @providers, languages: @languages, params: search_params %>
7-
<div class="card">
8-
<div class="card-header d-flex justify-content-between align-items-center">
9-
<h2 class="card-title">Topics</h2>
10-
<%= link_to new_topic_path, class: "btn btn-primary" do %>
11-
<i class="bi bi-plus"></i> Add New Topic
12-
<% end %>
13-
</div>
14-
<div class="card-content">
15-
<div class="card-body">
16-
<p class="card-text"> Some important information or instruction can be placed here.</p>
17-
<%= turbo_frame_tag "topic-list" do %>
18-
<div class="table-responsive">
19-
<table class="table table-lg table-striped mb-0">
20-
<thead>
21-
<tr>
22-
<th>Title</th>
23-
<th>Description</th>
24-
<th>UID</th>
25-
<th>Language</th>
26-
<th>Provider</th>
27-
<th>State</th>
28-
<th class="text-end">Actions</th>
29-
</tr>
30-
</thead>
31-
<%= render "list", topics: @topics %>
32-
</table>
33-
</div>
7+
<%= turbo_frame_tag "topics" do %>
8+
<div class="card">
9+
<div class="card-header d-flex justify-content-between align-items-center">
10+
<h2 class="card-title"><%= topics_title %></h2>
11+
<%= link_to new_topic_path, class: "btn btn-primary" do %>
12+
<i class="bi bi-plus"></i> Add New Topic
3413
<% end %>
3514
</div>
15+
<div class="card-content">
16+
<div class="card-body">
17+
<% if @available_providers.any? %>
18+
<%= render "choose_provider", providers: @available_providers %>
19+
<% end %>
20+
<p class="card-text"> Some important information or instruction can be placed here.</p>
21+
<%= turbo_frame_tag "topic-list" do %>
22+
<div class="table-responsive">
23+
<table class="table table-lg table-striped mb-0">
24+
<thead>
25+
<tr>
26+
<th>Title</th>
27+
<th>Description</th>
28+
<th>UID</th>
29+
<th>Language</th>
30+
<th>Provider</th>
31+
<th>State</th>
32+
<th class="text-end">Actions</th>
33+
</tr>
34+
</thead>
35+
<%= render "list", topics: @topics %>
36+
</table>
37+
</div>
38+
<% end %>
39+
</div>
40+
</div>
3641
</div>
37-
</div>
42+
<% end %>
3843
</div>
3944
</div>
4045
</section>

config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
resources :topics do
1010
put :archive, on: :member
1111
end
12+
resource :settings, only: [] do
13+
put :provider, on: :collection
14+
end
1215

1316
# Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb)
1417
# get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
require "rails_helper"
2+
3+
describe "Settings", type: :request do
4+
describe "PUT /settings/provider" do
5+
let(:user) { create(:user) }
6+
let(:provider) { create(:provider) }
7+
8+
before { sign_in(user) }
9+
10+
context "when provider cannot be found" do
11+
it "does not update current provider" do
12+
put provider_settings_url, params: { provider: { id: provider.id } }
13+
14+
expect(response).to have_http_status(:not_found)
15+
end
16+
end
17+
18+
context "when user has access to provider" do
19+
before do
20+
user.providers << provider
21+
end
22+
23+
it "updates current provider" do
24+
put provider_settings_url, params: { provider: { id: provider.id } }
25+
26+
signed_cookies = ActionDispatch::Request.new(Rails.application.env_config).cookie_jar
27+
28+
expect(response).to redirect_to(root_url)
29+
expect(signed_cookies.signed[:current_provider_id]).to eq(provider.id)
30+
end
31+
end
32+
end
33+
end

0 commit comments

Comments
 (0)