Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 29 additions & 26 deletions app/controllers/documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,15 @@ class DocumentsController < ApplicationController
before_action :set_document, only: %i[ show edit update destroy ]
protect_from_forgery :except => [:api_markdown]

def search_check(param)
if param.present?
key_words = param.split(/[\p{blank}\s]+/)
grouping_hash = key_words.reduce({}) {|hash, word| hash.merge(word => {content_or_creator_screen_name_or_description_or_project_name_or_location_cont: word})}
else
nil
end
end

def sort_check(param)
if param.present?
sort_column = []
sort_column << param
else
"start_at DESC"
end
end

# GET /documents or /documents.json
def index
if params[:q].nil?
@q = Document.ransack(params[:q])
@q.sorts = "start_at DESC"
else
@q = Document.ransack({combinator: 'and', groupings: search_check(params[:q][:content_or_creator_screen_name_or_description_or_project_name_or_location_cont])})
@q.sorts = sort_check(params[:q][:s])
end
@documents = @q.result.page(params[:page]).per(50).includes(:user)
search_query = { combinator: "and", groupings: split_into_search_queries(params.dig(:q, :text_cont)) }
search_query.merge!({ tags_id_eq: params[:tag_id] }) if params[:tag_id].present?

@q = Document.ransack(search_query)
@q.sorts = build_sort_query_with_default(params.dig(:q, :s))
@documents = @q.result.page(params[:page]).per(50).includes(:user, :creator, :project, :tags)
@tags = Tag.all
end

# GET /documents/1 or /documents/1.json
Expand Down Expand Up @@ -130,4 +111,26 @@ def parse_tag_names(tag_names)
end
end

# Build ransack AND search query from params
# Example: { text_cont: "foo bar" } => [{ text_cont: "foo" }, { text_cont: "bar" }]
def split_into_search_queries(param)
return nil if param.nil? || param.blank?

# Split keyword and build AND search condition
queries = []
words = param.split(/[\p{blank}\s]+/)
words.each do |word|
queries << { text_cont: word }
end

queries
end

def build_sort_query_with_default(param)
if param.present?
param
else
"start_at DESC"
end
end
end
70 changes: 37 additions & 33 deletions app/controllers/tasks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,22 @@ class TasksController < ApplicationController
before_action :set_task, only: %i[ show edit update destroy ]
before_action :get_form_data, only: %i[ new edit ]

def search_check(param)
if param.present?
key_words = param.split(/[\p{blank}\s]+/)
grouping_hash = key_words.reduce({}) { |hash, word| hash.merge(word => { content_or_assigner_screen_name_or_description_or_project_name_cont: word }) }
else
nil
end
end

def sort_check(param)
if param.present?
sort_column = []
sort_column << "state.priority DESC" << param
else
"state.priority DESC"
end
end

# GET /tasks or /tasks.json
def index
if params[:q].nil?
@q = Task.joins(:state).ransack(params[:q])
@q.sorts = ["state.priority DESC", "due_at ASC"]
else
@q = Task.joins(:state).ransack({combinator: 'and', groupings: search_check(params[:q][:content_or_assigner_screen_name_or_description_or_project_name_cont])})
@q.sorts = sort_check(params[:q][:s])
end
search_query = { combinator: "and", groupings: split_into_search_queries(params.dig(:q, :text_cont)) }

@show_all = params[:all] == 'true'
tasks_query = @q.result
session[:show_all] = params[:all] == 'true' if params[:all].present?
search_query.merge!({ assigner_id_eq: current_user.id }) unless session[:show_all]

if params[:only_todo] == '1'
tasks_query = tasks_query.merge(Task.active)
end

tasks_query = tasks_query.joins(:user).where(users: {screen_name: current_user&.screen_name}) unless @show_all
@tasks = tasks_query.page(params[:page]).per(50).includes(:user, :state)
session[:only_todo] = params[:only_todo] if params[:only_todo].present?
search_query.merge!({ task_state_id_eq: TaskState.where(name: "todo").first.id }) if session[:only_todo] == "1"

search_query.merge!({ tags_id_eq: params[:tag_id] }) if params[:tag_id].present?

@q = Task.ransack(search_query)
@q.sorts = build_sort_query_with_default(params.dig(:q, :s))
@tasks = @q.result.page(params[:page]).per(50).includes(:user, :project, :tags, :assigner, :state)
@tags = Tag.all
end

# GET /tasks/1 or /tasks/1.json
Expand Down Expand Up @@ -136,4 +115,29 @@ def parse_tag_names(tag_names)
tag ? tag : Tag.create(name: tag_name)
end
end

# Build ransack AND search query from params
# Example: { text_cont: "foo bar" } => [{ text_cont: "foo" }, { text_cont: "bar" }]
def split_into_search_queries(param)
return nil if param.nil? || param.blank?

# Split keyword and build AND search condition
queries = []
words = param.split(/[\p{blank}\s]+/)
words.each do |word|
queries << { text_cont: word }
end

queries
end

def build_sort_query_with_default(param)
query = ["state_priority DESC"]
if param.present?
query << param
else
query << "due_at ASC"
end
query
end
end
8 changes: 8 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ module ApplicationHelper
def tag_label(tag)
raw %(<span class="inline-block bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-0 rounded"> #{tag.name}</span>)
end

def url_with_query(url, key, value)
uri = URI(url)
query = Rack::Utils.parse_query(uri.query)
query[key] = value
uri.query = query.to_query
uri.to_s
end
end
13 changes: 13 additions & 0 deletions app/helpers/documents_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
module DocumentsHelper
def preserve_other_params(except: [])
forms = []
params.except(:controller, :action, :commit, *except).each do |key, value|
if key == 'q'
value.each do |q_key, q_value|
forms << hidden_field_tag("q[#{q_key}]", q_value)
end
else
forms << hidden_field_tag(key, value)
end
end
forms.join.html_safe
end
end
15 changes: 15 additions & 0 deletions app/helpers/tasks_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,19 @@ def days_to_deadline_as_string(task)
""
end
end

def preserve_other_params(except: [])
forms = []
params.except(:controller, :action, :commit, *except).each do |key, value|
if key == 'q'
value.each do |q_key, q_value|
forms << hidden_field_tag("q[#{q_key}]", q_value)
end
else
forms << hidden_field_tag(key, value)
end
end
p forms
forms.join.html_safe
end
end
4 changes: 3 additions & 1 deletion app/models/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ class Document < ApplicationRecord
#validates :project, presence: true
before_validation :add_unique_action_item_marker

ransack_alias :text, :content_or_creator_screen_name_or_description_or_project_name_or_location_cont

def self.ransackable_attributes(auth_object = nil)
["content", "created_at", "creator_id", "description", "end_at", "id", "location", "project_id", "start_at", "updated_at"]
["content", "created_at", "creator_id", "description", "end_at", "id", "location", "project_id", "start_at", "updated_at", "text"]
end

def self.ransackable_associations(auth_object = nil)
Expand Down
4 changes: 4 additions & 0 deletions app/models/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ class Tag < ApplicationRecord
has_many :documents, through: :document_tags, dependent: :restrict_with_exception
validates :name, presence: true, uniqueness: true

def self.ransackable_attributes(auth_object = nil)
[ "id", "name" ]
end

def self.order_by_popularity
self.find_by_sql <<~'SQL'
SELECT
Expand Down
6 changes: 4 additions & 2 deletions app/models/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ class Task < ApplicationRecord

validates :content, presence: true

ransack_alias :text, :content_or_assigner_screen_name_or_description_or_project_name

def self.ransackable_attributes(auth_object = nil)
[ "assigner_id", "content", "created_at", "creator_id", "description", "due_at", "id", "project_id", "tag_id", "task_state_id", "updated_at" ]
end
[ "assigner_id", "content", "created_at", "creator_id", "description", "due_at", "id", "project_id", "tag_id", "task_state_id", "updated_at", "text" ]
end

def self.ransackable_associations(auth_object = nil)
[ "assigner", "project", "state", "tags", "task_tags", "user" ]
Expand Down
11 changes: 8 additions & 3 deletions app/views/documents/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<% content_for :tag_list do %>
<%= render partial: "layouts/tag_list", locals: { base_link: request.original_url } %>
<% end %>

<div class="d-flex align-items-center">
<%= render 'layouts/h1', title: "文書一覧" %>
<div class="flex-grow-1"></div>
Expand All @@ -18,10 +22,11 @@

<div class="border p-3 my-3 rounded d-flex align-items-center gap-3">
<%= search_form_for @q, class: "d-flex align-items-center w-100" do |f| %>
<%= f.text_field :content_or_creator_screen_name_or_description_or_project_name_or_location_cont,
class: "form-control me-2",
placeholder: '検索ワードを入力して下さい',
<%= f.text_field :text_cont,
class: "form-control me-2",
placeholder: '検索ワードを入力して下さい',
style: "flex: 1;" %>
<%= preserve_other_params(except: [:q]) %>
<%= f.submit "検索", class: "btn btn-primary" %>
<% end %>
</div>
Expand Down
17 changes: 10 additions & 7 deletions app/views/layouts/_tag_list.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<div class="border mx-auto p-3 overflow-auto">
<p class="fw-bold fs-4 mb-3">タグ一覧</p>
<div class="d-flex flex-wrap gap-1">
<% Tag.order_by_popularity.each do |tag| %>
<%= link_to tag_label(tag), tag, class: "btn btn-primary btn-outline-primary" %>
<% end %>
<aside class="col-md-3 p-3">
<div class="border mx-auto p-3 overflow-auto">
<p class="fw-bold fs-4 mb-3">タグ一覧</p>
<div class="d-flex flex-wrap gap-1">
<% Tag.order_by_popularity.each do |tag| %>
<% link = base_link.present? ? url_with_query(base_link, "tag_id", tag.id) : tag_path(tag) %>
<%= link_to tag_label(tag), link, class: "btn btn-primary btn-outline-primary" %>
<% end %>
</div>
</div>
</div>
</aside>
4 changes: 1 addition & 3 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@

<div class="container-fluid">
<div class="row">
<aside class="col-md-3 p-3">
<%= render 'layouts/tag_list' %>
</aside>
<%= yield :tag_list %>

<main class="col-md-9">
<div class="container p-5">
Expand Down
34 changes: 19 additions & 15 deletions app/views/tasks/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<% content_for :tag_list do %>
<%= render partial: "layouts/tag_list", locals: { base_link: request.original_url } %>
<% end %>

<div class="d-flex align-items-center">
<%= render 'layouts/h1', title: "タスク一覧" %>
<div class="flex-grow-1"></div>
Expand All @@ -18,11 +22,11 @@

<div class="border p-3 my-3 rounded d-flex align-items-center gap-3">
<%= search_form_for @q, class: "d-flex align-items-center w-100" do |f| %>
<%= f.text_field :content_or_assigner_screen_name_or_description_or_project_name_cont,
class: "form-control me-2",
placeholder: '検索ワードを入力して下さい',
<%= f.text_field :text_cont,
class: "form-control me-2",
placeholder: '検索ワードを入力して下さい',
style: "flex: 1;" %>
<%= hidden_field_tag :only_todo, params[:only_todo] if params[:only_todo].present? %>
<%= preserve_other_params(except: [:q]) %>
<%= f.submit "検索", class: "btn btn-primary" %>
<% end %>
</div>
Expand All @@ -31,25 +35,25 @@
</div>

<%= form_with url: request.path, method: :get, local: true, html: { class: "d-flex" } do %>
<%= check_box_tag :only_todo, "1", params[:only_todo] == "1", onchange: "this.form.submit()" %>
<%= preserve_other_params(except: [:only_todo]) %>
<%= hidden_field_tag :only_todo, session[:only_todo] == '1' ? '0' : '1' %>
<%= check_box_tag "", "", checked: session[:only_todo] == "1", onchange: "this.form.submit()" %>
<div class="mx-1">
todoのみ
</div>

<% if params[:q].present? %>
<% params[:q].each do |key, value| %>
<%= hidden_field_tag "q[#{key}]", value %>
<% end %>
<% end %>
<% end %>

<% current_q_params = request.query_parameters.except(:controller, :action, :page) %>
<ul class="text-center nav nav-tabs" role="tablist">
<li class="nav-item w-50 bg-light">
<%= link_to "#{current_user&.screen_name}のタスク", tasks_path(current_q_params.merge(all: 'false')), class: "nav-link #{'active' if !@show_all} link-text" %>
<%= link_to "#{current_user&.screen_name}のタスク",
url_with_query(request.original_url, "all", "false"),
class: "nav-link #{'active' if !session[:show_all]} link-text" %>
</li>

<li class="nav-item w-50 bg-light">
<%= link_to 'すべてのタスク', tasks_path(current_q_params.merge(all: 'true')), class: "nav-link #{'active' if @show_all} link-text" %>
<%= link_to 'すべてのタスク',
url_with_query(request.original_url, "all", "true"),
class: "nav-link #{'active' if session[:show_all]} link-text" %>
</li>
</ul>

Expand All @@ -58,7 +62,7 @@
<%= render @tasks %>
<div class="row">
<div class="col-md-12 col-sm-12 text-center hidden-xs">
<%= raw(paginate @tasks, params: current_q_params) %>
<%= raw(paginate @tasks) %>
</div>
</div>
</div>
Expand Down