diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 01e1979e..e5362a90 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -1,4 +1,7 @@ @import "bootstrap"; +@import "documents"; +@import "tasks"; +@import "users"; /* * This is a manifest file that'll be compiled into application.css, which will include all the files * listed below. @@ -14,6 +17,12 @@ *= require_tree . *= require_self */ + +:root { + --bs-primary: #4a90e2; + --bs-primary-rgb: 74, 144, 226; + --bs-primary-bg-subtle: #e8f4fd; +} /*タブ切り替え全体のスタイル*/ .tabs { margin-top: 50px; @@ -21,18 +30,19 @@ background-color: #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); width: 700px; - margin: 0 auto;} + margin: 0 auto; +} /*タブのスタイル*/ .tab_item { - width: calc(100%/3); + width: calc(100% / 3); height: 50px; - border-bottom: 3px solid #5ab4bd; - background-color: #d9d9d9; + border-bottom: 3px solid var(--bs-primary); + background-color: var(--bs-light); line-height: 50px; font-size: 16px; text-align: center; - color: #565656; + color: var(--bs-gray-700); display: block; float: left; text-align: center; @@ -40,7 +50,7 @@ transition: all 0.2s ease; } .tab_item:hover { - opacity: 0.75; + background-color: var(--bs-gray-200); } /*ラジオボタンを全て消す*/ @@ -48,6 +58,16 @@ input[name="tab_item"] { display: none; } +/*ナビゲーションバーのホバー効果*/ +.navbar .nav-link:hover { + background-color: var(--bs-primary-bg-subtle); + border-radius: var(--bs-border-radius-sm); +} + +.navbar .btn:hover { + background-color: var(--bs-primary-bg-subtle); +} + /*タブ切り替えの中身のスタイル*/ .tab_content { display: none; @@ -56,7 +76,6 @@ input[name="tab_item"] { overflow: hidden; } - /*選択されているタブのコンテンツのみを表示*/ #all:checked ~ #all_content, #programming:checked ~ #programming_content, @@ -66,6 +85,41 @@ input[name="tab_item"] { /*選択されているタブのスタイルを変える*/ .tabs input:checked + .tab_item { - background-color: #5ab4bd; - color: #fff; + background-color: var(--bs-primary); + color: var(--bs-white); +} + +/*Bootstrap Iconsのサイズを大きくする*/ +.bi { + font-size: 1.3rem; +} + +/* タグ一覧サイドバー */ +.tag-list-container { + border-color: var(--bs-gray-200) !important; + background: var(--bs-gray-100); +} + +.tag-list-title { + color: var(--bs-gray-800); +} + +.tag-list-container .tag-badge { + border: 1px solid var(--bs-gray-300); + border-radius: var(--bs-border-radius-pill); + padding: 6px 14px; + display: inline-block; + transition: all 0.2s ease; + background: white; + color: var(--bs-gray-700); + text-decoration: none; + font-size: 0.9rem; +} + +.tag-list-container .tag-badge:hover { + background-color: var(--bs-primary); + color: white; + border-color: var(--bs-primary); + transform: translateY(-1px); + box-shadow: var(--bs-box-shadow-sm); } diff --git a/app/assets/stylesheets/documents.scss b/app/assets/stylesheets/documents.scss new file mode 100644 index 00000000..1308ccd9 --- /dev/null +++ b/app/assets/stylesheets/documents.scss @@ -0,0 +1,86 @@ +.card { + border: 1px solid var(--bs-gray-200); + border-radius: var(--bs-border-radius); + transition: all 0.2s ease; + position: relative; + cursor: pointer; + background: white; +} +.card:hover { + box-shadow: var(--bs-box-shadow-lg); + border-color: var(--bs-primary); +} +.card-link::after { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1; +} +.creator-badge, +.creator-badge a, +.card-body a:not(.card-link), +.btn { + position: relative; + z-index: 2; +} +.card-title { + font-size: 1.1rem; + font-weight: 500; + color: var(--bs-dark); +} +.text-black { + color: var(--bs-dark); + text-decoration: none; +} +.tag-badge { + border: 1px solid var(--bs-primary); + border-radius: var(--bs-border-radius-pill); + padding: 4px 8px; + display: inline-block; + background: white; + color: var(--bs-primary); + font-size: 0.85rem; + text-decoration: none; + font-weight: 500; + transition: all 0.2s ease; +} +.tag-badge:hover { + background-color: var(--bs-primary); + color: white; + border-color: var(--bs-primary); + transform: translateY(-1px); + box-shadow: var(--bs-box-shadow-sm); +} +.creator-badge { + border: 1px solid var(--bs-gray-400); + border-radius: var(--bs-border-radius-sm); + padding: 4px 8px; + display: inline-block; + transition: all 0.2s ease; + background: var(--bs-light); + font-size: 0.85rem; + color: var(--bs-gray-700); +} +.creator-badge:hover { + background-color: var(--bs-gray-200); + border-color: var(--bs-gray-500); +} +.creator-badge i { + margin-right: 2px; + font-size: 0.9rem; +} +.tag-badge i { + font-size: 0.75rem; +} +.card-body a[title="編集"] { + transition: all 0.2s ease; + padding: 4px 8px; + border-radius: var(--bs-border-radius-sm); +} +.card-body a[title="編集"]:hover { + color: var(--bs-primary) !important; + background-color: var(--bs-primary-bg-subtle); +} diff --git a/app/assets/stylesheets/tasks.scss b/app/assets/stylesheets/tasks.scss index 25986daa..73efd615 100644 --- a/app/assets/stylesheets/tasks.scss +++ b/app/assets/stylesheets/tasks.scss @@ -1,17 +1,132 @@ -.overdue_mark{ - color: rgb(230, 75, 75); - font-size: 14px; +.task-toolbar { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; +} + +.task-toolbar-panel { + border: 1px solid var(--bs-primary); + background: var(--bs-primary-bg-subtle); + border-radius: var(--bs-border-radius); + padding: 0.75rem 1rem; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0.75rem; +} + +.task-toolbar-label { + color: var(--bs-gray-700); + font-weight: 500; +} + +.task-sort-select { + width: auto; + border-color: var(--bs-gray-300); +} + +.task-icon-btn-primary { + color: var(--bs-primary); +} + +.task-icon-btn-muted { + color: var(--bs-secondary); +} + +.task-icon-btn-primary i:hover { + transform: scale(1.1); + transition: transform 0.2s ease; +} + +.task-card { + margin: 0; +} + +.task-state-btn i { + cursor: pointer; +} + +.task-creator-badge { + border: 1px solid var(--bs-gray-400); + border-radius: var(--bs-border-radius-sm); + padding: 4px 8px; + display: inline-block; + transition: all 0.2s ease; + background: var(--bs-light); + font-size: 0.85rem; + color: var(--bs-gray-700); +} + +.task-creator-badge:hover { + background-color: var(--bs-gray-200); + border-color: var(--bs-gray-500); +} + +.task-tag-list { + min-height: 24px; +} + +.task-date-row { + min-height: 24px; +} + +.task-project-badge { + border: 1px solid var(--bs-gray-400); + border-radius: var(--bs-border-radius-pill); + padding: 2px 8px; + display: inline-block; + background: var(--bs-light); + color: var(--bs-gray-700); + font-size: 0.75rem; + text-decoration: none; + line-height: 1.4; + transition: all 0.2s ease; +} + +.task-project-badge:hover { + background-color: var(--bs-gray-200); + border-color: var(--bs-gray-500); + color: var(--bs-gray-800); +} + +.task-tag-badge { + border: 1px solid var(--bs-primary); + border-radius: var(--bs-border-radius-pill); + padding: 4px 8px; + display: inline-block; + background: white; + color: var(--bs-primary); + font-size: 0.85rem; + text-decoration: none; + font-weight: 500; + transition: all 0.2s ease; +} + +.task-tag-badge:hover { + background-color: var(--bs-primary); + color: white; + border-color: var(--bs-primary); + transform: translateY(-1px); + box-shadow: var(--bs-box-shadow-sm); +} + +.task-deadline { + margin: 0; + font-size: 0.85rem; text-align: right; + white-space: nowrap; } -.ongoing_mark{ +.task-deadline-overdue { + color: rgb(230, 75, 75); +} + +.task-deadline-ongoing { color: #1c501c; - font-size: 14px; - text-align: right; } -.dropdown-menu{ - background-color: #FFF5EE; - padding: 5px 5px 5px 5px; +.dropdown-menu { + background-color: #fff5ee; + padding: 5px; border: 1pt solid #000000; } diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index f2945654..cc71570e 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -7,11 +7,11 @@ class TasksController < ApplicationController def index search_query = { combinator: "and", groupings: split_into_search_queries(params.dig(:q, :text_cont)) } - session[:show_all] = params[:all] == 'true' if params[:all].present? + session[:show_all] = params[:all] == "true" if params[:all].present? search_query.merge!({ assigner_id_eq: current_user.id }) unless session[:show_all] session[:only_todo] = params[:only_todo] if params[:only_todo].present? - search_query.merge!({ task_state_id_eq: TaskState.todo.id }) if session[:only_todo] == "1" + search_query.merge!({ task_state_id_eq: TaskState.todo.id }) if session[:only_todo] != "0" search_query.merge!({ tags_id_eq: params[:tag_id] }) if params[:tag_id].present? diff --git a/app/helpers/documents_helper.rb b/app/helpers/documents_helper.rb index 8900fb76..127e9db1 100644 --- a/app/helpers/documents_helper.rb +++ b/app/helpers/documents_helper.rb @@ -12,4 +12,27 @@ def preserve_other_params(except: []) end forms.join.html_safe end + + def sort_options + [ + { value: 'content_asc', label: 'タイトル順(昇順)' }, + { value: 'content_desc', label: 'タイトル順(降順)' }, + { value: 'updated_at_asc', label: '更新順(古い順)' }, + { value: 'updated_at_desc', label: '更新順(新しい順)' }, + { value: 'created_at_asc', label: '作成順(古い順)' }, + { value: 'created_at_desc', label: '作成順(新しい順)' }, + { value: 'start_at_asc', label: '開始時刻順(昇順)' }, + { value: 'start_at_desc', label: '開始時刻順(降順)' } + ] + end + + def current_sort_value(q) + current_sort = q.sorts.first&.name + if current_sort.present? + direction = q.sorts.first&.dir + "#{current_sort}_#{direction}" + else + 'content_asc' + end + end end diff --git a/app/helpers/tasks_helper.rb b/app/helpers/tasks_helper.rb index b153400b..d2300fde 100644 --- a/app/helpers/tasks_helper.rb +++ b/app/helpers/tasks_helper.rb @@ -1,4 +1,24 @@ module TasksHelper + def sort_options + [ + { value: 'updated_at_desc', label: '更新順(新しい順)' }, + { value: 'updated_at_asc', label: '更新順(古い順)' }, + { value: 'created_at_desc', label: '作成順(新しい順)' }, + { value: 'created_at_asc', label: '作成順(古い順)' }, + { value: 'due_at_asc', label: '期限順(近い順)' }, + { value: 'due_at_desc', label: '期限順(遠い順)' }, + { value: 'project_id_asc', label: 'プロジェクト名順(昇順)' }, + { value: 'project_id_desc', label: 'プロジェクト名順(降順)' } + ] + end + + def current_sort_value(q) + current_sort = q.sorts.find { |sort| sort.name != 'state_priority' } + return 'due_at_asc' if current_sort.blank? + + "#{current_sort.name}_#{current_sort.dir}" + end + def days_to_deadline_as_string(task) days = task.days_to_deadline if days.finite? @@ -19,7 +39,6 @@ def preserve_other_params(except: []) forms << hidden_field_tag(key, value) end end - p forms forms.join.html_safe end end diff --git a/app/javascript/application.js b/app/javascript/application.js index 16fb158f..3298ada7 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,4 +1,5 @@ // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails import "@hotwired/turbo-rails" import "controllers" -import "documents" \ No newline at end of file +import "documents" +import "bootstrap" diff --git a/app/views/documents/_document.html.erb b/app/views/documents/_document.html.erb index 81313fd2..6427fba2 100644 --- a/app/views/documents/_document.html.erb +++ b/app/views/documents/_document.html.erb @@ -1,38 +1,34 @@ -
- <%= link_to document.content.truncate(20), document, class: "text-black text-small" %> -
-
- <%= link_to_if document.creator&.screen_name, document.creator&.name, document.creator, class: "text-black text-decoration-none" %>
- ,
- <%= document.start_at&.strftime('%Y/%m/%d') %>
-
+
+ <%= link_to document.content.truncate(30), document, class: "text-black text-decoration-none card-link" %>
+
+
+
| ソート: | -<%= sort_link(@q, :content, "タイトル順") %> | -<%= sort_link(@q, :updated_at, "更新順") %> | -<%= sort_link(@q, :created_at, "作成順") %> | -<%= sort_link(@q, :start_at, "開始時刻順") %> | -
|---|