Skip to content

Commit

Permalink
Data Table: Bot Accounts (#849)
Browse files Browse the repository at this point in the history
* start migrating project bot accounts to use data table component

* fix response for create bot

* fix remaining logic after each action associated with bot table

* some cleanup, fix some tests

* update project bots PAT table and responses

* update checkbox to use primary color

* migrate groups bots to use data table

* fix tests

* cleanup, move pagy to table partial

* fix translations

* refactor PAT tables into component

* refactor bot accounts table to use share component

* refactor translations

* finish refactoring translations

* refactor PAT translations

* fix translations in tests

* cleanup, add rubocop disable

* fix translations

* run normalize

* fix tests after translation change

* move mb-4 from wrapper to turbo frame

* remove whitespace for some classes
  • Loading branch information
ChrisHuynh333 authored Dec 19, 2024
1 parent 2e16b32 commit 13ecb2f
Show file tree
Hide file tree
Showing 52 changed files with 534 additions and 958 deletions.
77 changes: 77 additions & 0 deletions app/components/bots/table_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<% if @bot_accounts.count.positive? %>
<%= viral_data_table(@bot_accounts, id: "bots-table") do |table| %>
<% table.with_column(t("bots.index.table.header.username")) do |row| %>
<%= row.user.email %>
<% end %>
<% table.with_column(t("bots.index.table.header.active_tokens")) do |row| %>
<% if row.user.personal_access_tokens.active.count.positive? %>
<%= link_to row.user.personal_access_tokens.active.count,
bot_tokens_path(row),
data: {
turbo_stream: true,
},
class: "font-semibold text-slate-800 dark:text-slate-300 hover:underline" %>
<% else %>
0
<% end %>
<% end %>
<% table.with_column(t("bots.index.table.header.created")) do |row| %>
<%= helpers.local_time_ago(row.user.created_at) %>
<% end %>
<% table.with_column(t("bots.index.table.header.access_level")) do |row| %>
<% unless row.membership.nil? %>
<%= t(:"bots.index.table.access_level.level_#{row.membership.access_level}") %>
<% end %>
<% end %>
<% table.with_column(t("bots.index.table.header.expiration")) do |row| %>
<% if !row.membership&.expires_at.nil? %>
<%= helpers.local_time(row.membership.expires_at, :full_date) %>
<% else %>
<%= t("bots.index.table.never") %>
<% end %>
<% end %>
<% table.with_column(t("bots.index.table.header.actions"),
sticky_key: :right
) do |row| %>
<% if @abilities[:generate_token] %>
<%= link_to(
t("bots.index.table.actions.generate_new_token"),
new_token_path(row),
data: {
turbo_stream: true,
},
aria: {
label: t("bots.index.table.actions.generate_new_token_aria_label"),
},
class:
"font-medium text-blue-600 underline dark:text-blue-500 hover:no-underline cursor-pointer",
) %>
<% end %>
<% if @abilities[:destroy_bot] %>
<%= link_to(
t("bots.index.table.actions.destroy"),
destroy_path(row),
data: {
turbo_method: :delete,
turbo_confirm: t("bots.index.table.actions.destroy_confirmation"),
turbo_frame: "_top",
},
aria: {
label: t("bots.index.table.actions.destroy_aria_label"),
},
class:
"font-medium text-blue-600 underline dark:text-blue-500 hover:no-underline cursor-pointer",
) %>
<% end %>
<% end %>
<% end %>
<%= render Viral::Pagy::FullComponent.new(@pagy, item: t("bots.index.pagy_item")) %>
<% else %>
<div class="empty_state_message">
<%= viral_empty(
title: t("bots.index.table.empty_state.title"),
description: t("bots.index.table.empty_state.description"),
icon_name: :bug_ant,
) %>
</div>
<% end %>
54 changes: 54 additions & 0 deletions app/components/bots/table_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require 'ransack/helpers/form_helper'

module Bots
# Component for rendering the PersonalAccessTokens tables
class TableComponent < Component
include Ransack::Helpers::FormHelper

# rubocop: disable Metrics/ParameterLists
def initialize(
bot_accounts,
namespace,
pagy,
abilities: {},
empty: {},
**system_arguments
)
@bot_accounts = bot_accounts
@namespace = namespace
@pagy = pagy
@abilities = abilities
@empty = empty
@system_arguments = system_arguments
end
# rubocop: enable Metrics/ParameterLists

private

def bot_tokens_path(bot)
if @namespace.is_a?(Group)
group_bot_personal_access_tokens_path(bot_id: bot.id)
elsif @namespace.is_a?(Namespaces::ProjectNamespace)
namespace_project_bot_personal_access_tokens_path(bot_id: bot.id)
end
end

def new_token_path(bot)
if @namespace.is_a?(Group)
new_group_bot_personal_access_token_path(bot_id: bot.id)
elsif @namespace.is_a?(Namespaces::ProjectNamespace)
new_namespace_project_bot_personal_access_token_path(bot_id: bot.id)
end
end

def destroy_path(bot)
if @namespace.is_a?(Group)
group_bot_path(id: bot.id)
elsif @namespace.is_a?(Namespaces::ProjectNamespace)
namespace_project_bot_path(id: bot.id)
end
end
end
end
49 changes: 49 additions & 0 deletions app/components/personal_access_tokens/table_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<% if @personal_access_tokens.count.positive? %>
<%= viral_data_table(@personal_access_tokens, id: "access-tokens-table") do |table| %>
<% table.with_column(t("personal_access_tokens.table.header.name")) do |row| %>
<%= row[:name] %>
<% end %>
<% table.with_column(t("personal_access_tokens.table.header.scopes")) do |row| %>
<%= row[:scopes].join(", ") %>
<% end %>
<% table.with_column(t("personal_access_tokens.table.header.created_at")) do |row| %>
<%= helpers.local_time(row[:created_at], :full_date) %>
<% end %>
<% table.with_column(t("personal_access_tokens.table.header.last_used_at")) do |row| %>
<% if row[:last_used_at].present? %>
<%= helpers.local_time(row[:last_used_at], :full_date) %>
<% else %>
<%= t("personal_access_tokens.table.never") %>
<% end %>
<% end %>
<% table.with_column(t("personal_access_tokens.table.header.expires_at")) do |row| %>
<% if row[:expires_at].present? %>
<%= helpers.local_time(row[:expires_at], :full_date) %>
<% else %>
<%= t("personal_access_tokens.table.never") %>
<% end %>
<% end %>
<% table.with_column(t("personal_access_tokens.table.header.action"),
sticky_key: :right
) do |row| %>
<%= link_to(
t("personal_access_tokens.table.revoke"),
revoke_path(row),
data: {
turbo_method: :delete,
turbo_confirm: t("personal_access_tokens.table.revoke_confirmation"),
},
class:
"font-medium text-blue-600 underline dark:text-blue-500 hover:no-underline cursor-pointer",
) %>
<% end %>
<% end %>
<% else %>
<div class="empty_state_message">
<%= viral_empty(
title: @empty[:title],
description: @empty[:description],
icon_name: :bug_ant,
) %>
</div>
<% end %>
42 changes: 42 additions & 0 deletions app/components/personal_access_tokens/table_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require 'ransack/helpers/form_helper'

module PersonalAccessTokens
# Component for rendering the PersonalAccessTokens tables
class TableComponent < Component
include Ransack::Helpers::FormHelper

def initialize(
personal_access_tokens,
namespace: nil,
bot_account: nil,
empty: {},
**system_arguments
)
@personal_access_tokens = personal_access_tokens
@namespace = namespace
@bot_account = bot_account
@empty = empty
@system_arguments = system_arguments
end

private

def revoke_path(token)
if @namespace.is_a?(Group)
revoke_group_bot_personal_access_token_path(
bot_id: @bot_account.id,
id: token.id
)
elsif @namespace.is_a?(Namespaces::ProjectNamespace)
revoke_namespace_project_bot_personal_access_token_path(
bot_id: @bot_account.id,
id: token.id
)
else
revoke_profile_personal_access_token_path(id: token.id)
end
end
end
end
16 changes: 7 additions & 9 deletions app/controllers/concerns/bot_actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ module BotActions
before_action proc { access_levels }
before_action proc { bot_account }, only: %i[destroy]
before_action proc { bot_type }, only: %i[create]
before_action proc { bot_accounts }
end

def index
authorize! @namespace, to: :view_bot_accounts?

@pagy, @bot_accounts = pagy(load_bot_accounts)
@pagy, @bot_accounts = pagy(@bot_accounts)
end

def new
Expand Down Expand Up @@ -52,16 +53,13 @@ def create # rubocop:disable Metrics/MethodLength
end
end

def destroy # rubocop:disable Metrics/MethodLength
def destroy
Bots::DestroyService.new(@bot_account, current_user).execute

respond_to do |format|
format.turbo_stream do
if @bot_account.deleted?
render status: :ok, locals: {
type: 'success',
message: t('concerns.bot_actions.destroy.success')
}
flash[:success] = t('concerns.bot_actions.destroy.success')
redirect_to redirect_path
else
render status: :unprocessable_entity,
locals: {
Expand All @@ -83,7 +81,7 @@ def access_levels
@access_levels = Member::AccessLevel.access_level_options_for_user(@namespace, current_user)
end

def load_bot_accounts
@namespace.namespace_bots.includes(:user)
def bot_accounts
@bot_accounts = @namespace.namespace_bots.includes(:user)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ module BotPersonalAccessTokenActions
included do
before_action proc { namespace }
before_action proc { bot_account }
before_action proc { personal_access_tokens }, only: %i[index]
before_action proc { personal_access_tokens }, only: %i[index revoke]
before_action proc { personal_access_token }, only: %i[revoke]
before_action proc { bot_accounts }
end

def index
Expand Down Expand Up @@ -84,4 +85,8 @@ def personal_access_tokens
def personal_access_token
@personal_access_token = @bot_account.user.personal_access_tokens.find_by(id: params[:id]) || not_found
end

def bot_accounts
@bot_accounts = @namespace.namespace_bots.includes(:user)
end
end
4 changes: 4 additions & 0 deletions app/controllers/groups/bots_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,9 @@ def current_page
def bot_type
@bot_type = User.user_types[:group_bot]
end

def redirect_path
group_bots_path
end
end
end
4 changes: 4 additions & 0 deletions app/controllers/projects/bots_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,9 @@ def current_page
def bot_type
@bot_type = User.user_types[:project_bot]
end

def redirect_path
namespace_project_bots_path
end
end
end
16 changes: 4 additions & 12 deletions app/views/groups/bots/_access_token_section.html.erb
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
<%= turbo_frame_tag "access-token-section" do %>
<div
data-turbo-temporary
data-turbo-permanent
class="
p-4
bg-white
border
border-slate-200
rounded-lg
shadow-sm
2xl:col-span-2
dark:border-slate-700
sm:p-6
dark:bg-slate-800
p-4 bg-white border border-slate-200 rounded-lg shadow-sm 2xl:col-span-2
dark:border-slate-700 sm:p-6 dark:bg-slate-800 mb-4
"
>
<h2 class="text-xl font-semibold leading-tight text-slate-900 dark:text-white">
Expand All @@ -20,7 +12,7 @@
<%= render TokenComponent.new(
value: token,
aria_label: t("groups.bots.index.access_token_section.aria_label"),
classes: "my-2"
classes: "my-2",
) %>
<p class="text-slate-500 dark:text-slate-400"><%= t("groups.bots.index.access_token_section.description") %></p>
</div>
Expand Down
Loading

0 comments on commit 13ecb2f

Please sign in to comment.