-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ENHC0010038] Components/groups search and sort (#656)
* Create template table component files * Incorporate template into the groups table * Change the Groups tab to use the new table component * Create search box * Add starting search functionality * Remove debug code * Refactor code to utilize table_component.rb * Modify sorting to exclude the Access Granted column * Add ability to search by group name * Remove html tag that causes test failures * Add starting test for groups search * Add table component to create and destroy turbo streams * Add tests for searching groups * Modify Ransack to use the proper attributes * Add abilities variable to reduce helpers calls * Create tests for column sorting * Cleanup debug code and comments * Create tests for the table component * Clean up code in table component tests * Convert group group links to use the table component * Fix failed tests caused by group link creation and deletion * Add functionality to search form to search members and group links * Update groups search box to use the search_url variable * Incorporate search component into groups search * Add more tests for the groups group links * Clean up unnecessary code and comments * Add ability to sort the Access Granted column * Fix spelling in fr.yml file * Add missing french keys
- Loading branch information
Showing
22 changed files
with
688 additions
and
143 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
en: | ||
group_name: Group | ||
namespace_name: Source | ||
updated_at: Access Granted | ||
group_access_level: Access Level | ||
expires_at: Expiration | ||
action: Action |
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,7 @@ | ||
fr: | ||
group_name: Group | ||
namespace_name: Source | ||
updated_at: Access Granted | ||
group_access_level: Access Level | ||
expires_at: Expiration | ||
action: Action |
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,173 @@ | ||
<%= render Viral::BaseComponent.new(**wrapper_arguments) do %> | ||
<table | ||
class=' | ||
w-full text-sm text-left rtl:text-right text-slate-500 dark:text-slate-400 | ||
whitespace-nowrap | ||
' | ||
> | ||
<thead | ||
class=' | ||
text-xs text-slate-700 uppercase bg-slate-50 dark:bg-slate-700 | ||
dark:text-slate-400 | ||
' | ||
> | ||
<tr> | ||
<% @columns.each_with_index do |column, index| %> | ||
<%= render_cell( | ||
tag: 'th', | ||
scope: 'col', | ||
classes: class_names('px-6 py-3', 'sticky left-0 z-10 flex': index.zero?) | ||
) do %> | ||
<%= render Ransack::SortComponent.new( | ||
ransack_obj: @q, | ||
label: t(".#{column}"), | ||
url: helpers.sorting_url(@q, column), | ||
field: column, | ||
) %> | ||
<% end %> | ||
<% end %> | ||
<%= render_cell( | ||
tag: 'th', | ||
scope: 'col', | ||
classes: class_names('px-6 py-3 bg-slate-50 dark:bg-slate-700 sticky right-0') | ||
) do %> | ||
<%= t(".action") %> | ||
<% end %> | ||
</tr> | ||
</thead> | ||
<tbody | ||
class=' | ||
bg-white divide-y divide-slate-200 dark:bg-slate-800 dark:divide-slate-700 | ||
' | ||
> | ||
<% @namespace_group_links.each do | namespace_group_link | %> | ||
<%= render Viral::BaseComponent.new(**row_arguments(namespace_group_link)) do %> | ||
<% namespace_group_link_source = | ||
helpers.namespace_group_link_source(@namespace, namespace_group_link) %> | ||
<td class="px-6 py-4"><%= namespace_group_link.group.name %></td> | ||
<td class="px-6 py-4"> | ||
<% if namespace_group_link_source.key?(:inherited_namespace_path) %> | ||
<%= viral_tooltip(title: t(:"projects.group_links.index.inherited_from")) do %> | ||
<%= link_to namespace_group_link_source[:label], | ||
namespace_group_link_source[:inherited_namespace_path], | ||
data: { | ||
turbo_frame: "_top", | ||
}, | ||
class: "text-grey-900 dark:text-grey-100 font-semibold hover:underline" %> | ||
<% end %> | ||
<% else %> | ||
<div class="text-sm font-normal text-slate-500 dark:text-slate-400"> | ||
<%= namespace_group_link_source[:label] %> | ||
</div> | ||
<% end %> | ||
</td> | ||
<td class="px-6 py-4"> | ||
<div> | ||
<%= viral_time_ago(original_time: namespace_group_link.created_at) %> | ||
<span class="block"> | ||
<%= helpers.turbo_frame_tag("invited-group-#{namespace_group_link.group.id}-updated") do %> | ||
<% if namespace_group_link.created_at < namespace_group_link.updated_at %> | ||
<%= render UpdatedComponent.new(updated_at: namespace_group_link.updated_at) %> | ||
<% end %> | ||
<% end %> | ||
</span> | ||
</div> | ||
</td> | ||
<td class="px-6 py-4"> | ||
<div class="form-field"> | ||
<% if @abilities[:update_namespace] && !namespace_group_link_source.key?(:inherited_namespace_path) %> | ||
<%= form_with(model: namespace_group_link, url: select_group_link_path(namespace_group_link), method: :patch) do |form| %> | ||
<%= form.select( | ||
:group_access_level, | ||
@access_levels, | ||
{ selected: namespace_group_link.group_access_level }, | ||
{ | ||
id: "invited-group-#{namespace_group_link.group.id}-access-level-select", | ||
onchange: "this.form.requestSubmit();", | ||
"aria-label": | ||
t(:"projects.group_links.index.aria_labels.group_access_level"), | ||
}, | ||
) %> | ||
<input type="hidden" name="format" value="turbo_stream"/> | ||
<% end %> | ||
<% else %> | ||
<%= t( | ||
:"projects.group_links.index.access_level.level_#{namespace_group_link.group_access_level}", | ||
) %> | ||
<% end %> | ||
</div> | ||
</td> | ||
<td class="px-6 py-4"> | ||
<% if @abilities[:update_namespace] && !namespace_group_link_source.key?(:inherited_namespace_path) %> | ||
<%= form_with( model: namespace_group_link, url: select_group_link_path(namespace_group_link), method: :patch) do |form| %> | ||
<div class="form-field datepicker" data-controller="datepicker"> | ||
<div class="relative max-w-sm"> | ||
<div | ||
class=" | ||
absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none | ||
" | ||
> | ||
<%= viral_icon( | ||
name: :calendar_days, | ||
classes: "w-5 h-5 text-slate-500 dark:text-slate-400", | ||
) %> | ||
</div> | ||
<%= form.text_field :expires_at, | ||
placeholder: I18n.t("date.formats.iso"), | ||
autocomplete: "off", | ||
value: namespace_group_link.expires_at, | ||
id: "invited-group-#{namespace_group_link.group.id}-expiration", | ||
"data-datepicker-target": "datePicker", | ||
"data-datepicker-autosubmit": "true", | ||
"aria-label": | ||
t(:"projects.group_links.index.aria_labels.expires_at") %> | ||
|
||
<input type="hidden" name="format" value="turbo_stream"/> | ||
</div> | ||
</div> | ||
<% end %> | ||
<% else %> | ||
<%= namespace_group_link.expires_at %> | ||
<% end %> | ||
</td> | ||
<td class="px-6 py-4 space-x-2"> | ||
<% if @abilities[:unlink_group] && !namespace_group_link_source.key?(:inherited_namespace_path) %> | ||
<%= link_to( | ||
t(:"projects.group_links.index.unlink"), | ||
select_group_link_path(namespace_group_link), | ||
data: { | ||
turbo_method: :delete, | ||
turbo_confirm: | ||
t( | ||
:"projects.group_links.index.unlink_confirmation", | ||
namespace_name: namespace_group_link.namespace.human_name, | ||
group_name: namespace_group_link.group.human_name, | ||
), | ||
turbo_stream: true, | ||
}, | ||
aria: { | ||
label: | ||
( | ||
t( | ||
:"projects.group_links.index.actions.unlink_aria_label", | ||
member: namespace_group_link.group.name, | ||
) | ||
), | ||
}, | ||
class: | ||
"font-medium text-blue-600 underline dark:text-blue-500 hover:no-underline cursor-pointer", | ||
) %> | ||
<% end %> | ||
</td> | ||
<% end %> | ||
<% end %> | ||
</tbody> | ||
</table> | ||
<div class="empty_state_message"> | ||
<%= viral_empty( | ||
title: t(:"projects.group_links.index.empty_state.title"), | ||
description: t(:"projects.group_links.index.empty_state.description"), | ||
icon_name: :document_text, | ||
) %> | ||
</div> | ||
<% 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,61 @@ | ||
# frozen_string_literal: true | ||
|
||
module Groups | ||
# Component for rendering a table of Samples | ||
class TableComponent < Component | ||
include Ransack::Helpers::FormHelper | ||
|
||
# rubocop:disable Naming/MethodParameterName,Metrics/ParameterLists | ||
def initialize( | ||
namespace_group_links, | ||
namespace, | ||
access_levels, | ||
q, | ||
abilities: {}, | ||
**system_arguments | ||
) | ||
@namespace_group_links = namespace_group_links | ||
@namespace = namespace | ||
@access_levels = access_levels | ||
@q = q | ||
@abilities = abilities | ||
@system_arguments = system_arguments | ||
|
||
@columns = columns | ||
end | ||
# rubocop:enable Naming/MethodParameterName,Metrics/ParameterLists | ||
|
||
def wrapper_arguments | ||
{ | ||
tag: 'div', | ||
classes: class_names('table-container relative overflow-x-auto'), | ||
data: { turbo: :temporary } | ||
} | ||
end | ||
|
||
def row_arguments(namespace_group_link) | ||
{ tag: 'tr' }.tap do |args| | ||
args[:classes] = class_names('bg-white', 'border-b', 'dark:bg-slate-800', 'dark:border-slate-700') | ||
args[:id] = dom_id(namespace_group_link) | ||
end | ||
end | ||
|
||
def render_cell(**arguments, &) | ||
render(Viral::BaseComponent.new(**arguments), &) | ||
end | ||
|
||
def select_group_link_path(namespace_group_link) | ||
if @namespace.type == 'Group' | ||
group_group_link_path(@namespace, namespace_group_link) | ||
else | ||
namespace_project_group_link_path(@namespace.parent, @namespace.project, namespace_group_link) | ||
end | ||
end | ||
|
||
private | ||
|
||
def columns | ||
%i[group_name namespace_name updated_at group_access_level expires_at] | ||
end | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,11 @@ | ||
<div class="table-container relative overflow-x-auto" data-turbo-temporary> | ||
<table | ||
class=" | ||
w-full | ||
text-sm | ||
text-left | ||
rtl:text-right | ||
text-slate-500 | ||
dark:text-slate-400 | ||
dark:divide-slate-600 | ||
whitespace-nowrap | ||
" | ||
> | ||
<thead | ||
class=" | ||
text-xs | ||
text-slate-700 | ||
uppercase | ||
bg-slate-50 | ||
dark:bg-slate-700 | ||
dark:text-slate-400 | ||
" | ||
> | ||
<tr> | ||
<th scope="col" class="px-6 py-3"><%= t(:"groups.group_links.index.table_header.group") %></th> | ||
<th scope="col" class="px-6 py-3"><%= t(:"groups.group_links.index.table_header.source") %></th> | ||
<th scope="col" class="px-6 py-3"><%= t(:"groups.group_links.index.table_header.access_granted") %></th> | ||
<th scope="col" class="px-6 py-3 min-w-40"><%= t(:"groups.group_links.index.table_header.access_level") %></th> | ||
<th scope="col" class="px-6 py-3 min-w-48"><%= t(:"groups.group_links.index.table_header.expiration") %></th> | ||
<th scope="col" class="px-6 py-3"><%= t(:"groups.group_links.index.table_header.action") %></th> | ||
</tr> | ||
</thead> | ||
<tbody | ||
id="invited-groups-table-body" | ||
class=" | ||
bg-white | ||
divide-y | ||
divide-slate-200 | ||
dark:bg-slate-800 | ||
dark:divide-slate-700 | ||
" | ||
> | ||
<%= render partial: "namespace_group_link", collection: @namespace_group_links %> | ||
</tbody> | ||
</table> | ||
<div class="empty_state_message"> | ||
<%= viral_empty( | ||
title: t(:"groups.group_links.index.empty_state.title"), | ||
description: t(:"groups.group_links.index.empty_state.description"), | ||
icon_name: :document_text | ||
) %> | ||
</div> | ||
</div> | ||
<%= render Groups::TableComponent.new( | ||
@namespace_group_links, | ||
@namespace, | ||
@access_levels, | ||
@q, | ||
abilities: { | ||
update_namespace: | ||
allowed_to?(:update_namespace_with_group_link?, @namespace), | ||
unlink_group: allowed_to?(:unlink_namespace_with_group?, @namespace), | ||
}, | ||
) %> |
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.