Skip to content

Commit

Permalink
feat: page for removing team members from team
Browse files Browse the repository at this point in the history
  • Loading branch information
kjellberg committed Apr 4, 2024
1 parent 8d7e98a commit aa1090e
Show file tree
Hide file tree
Showing 17 changed files with 249 additions and 11 deletions.
26 changes: 26 additions & 0 deletions app/assets/stylesheets/application.tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,33 @@
@apply border-border bg-button inline-block cursor-pointer rounded px-5 py-2 font-bold text-white no-underline;
}

.button.xs {
@apply px-3 py-1 text-sm;
}

.button.danger {
@apply bg-rose-500;
}

.kiqr-table {
width: calc(100% + 4rem);
@apply -mx-8;
}

.kiqr-table thead {
@apply border-border;
}

.kiqr-table thead th {
@apply text-text;
}

.kiqr-table tbody tr {
@apply text-text px-5 border-border odd:bg-gray-100 even:bg-gray-50 dark:odd:bg-stone-900 dark:even:bg-stone-800;
}

.kiqr-table th,
.kiqr-table td {
@apply p-2 px-4 first:pl-8 last:pr-8;
}
}
40 changes: 40 additions & 0 deletions app/controllers/accounts/members_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Accounts::MembersController < ApplicationController
before_action :ensure_team_account
before_action :setup_account

def index
end

def edit
@account_user = @account.account_users.find_puid!(params[:id])
end

def destroy
@account_user = @account.account_users.find_puid!(params[:id])
if @account_user.destroy
flash[:notice] = I18n.t("account_users.destroy.success")
redirect_to members_path
else
flash[:alert] = I18n.t("account_users.destroy.failure")
redirect_to members_path, status: :unprocessable_entity
end
end

private

def ensure_team_account
redirect_to edit_account_path if current_account.personal?
end

def setup_account
@account = current_account
@members = current_account.account_users
end

def options_for_roles
AccountUser::ROLES.map do |role|
[I18n.t("account_users.roles.#{role}"), role]
end
end
helper_method :options_for_roles
end
6 changes: 4 additions & 2 deletions app/controllers/concerns/set_current_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ module SetCurrentAttributes

included do
before_action do
Current.user = current_user
Current.account = (fetch_account_from_params || current_user&.personal_account) if user_signed_in?
if user_signed_in?
Current.user = current_user
Current.account = (fetch_account_from_params || current_user&.personal_account)
end
end
end

Expand Down
16 changes: 14 additions & 2 deletions app/models/account_user.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
class AccountUser < ApplicationRecord
ROLES = %w[owner member]
class AccountUser < ApplicationRecord # This will generate a public_uid for the model when it is created.
# Use this public_uidas a unique public identifier for the model.
# To find a model by its public_uid, use the following method:
# Account.find_puid('xxxxxxxx')
# Learn more: https://github.com/equivalent/public_uid
include PublicUid::ModelConcern

# This is a list of roles that a user can have in an account.
# You can add more roles if you want, but you SHOULD NOT REMOVE
# the owner role, as it is required for the account to function.
ROLES = %w[owner admin readonly]

belongs_to :user
belongs_to :account

# The name of the account user.
delegate :name, to: :user

validates :role, presence: true, inclusion: {in: self::ROLES}
end
3 changes: 3 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class User < ApplicationRecord
has_many :account_users, dependent: :destroy
has_many :accounts, through: :account_users

# Get the user's full name from their personal account.
delegate :name, to: :personal_account

def onboarded?
personal_account.present? && personal_account.persisted?
end
Expand Down
5 changes: 5 additions & 0 deletions app/views/accounts/members/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= simple_form_for(account_user, url: "#") do |f| %>
<div class="mt-4 flex justify-between items-center">
<%= f.button :submit, t(".submit") %>
</div>
<% end %>
15 changes: 15 additions & 0 deletions app/views/accounts/members/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<% title t(".title") %>
<%= render(PageLayouts::Settings::Component.new(
title: t(".title"),
description: t(".description")
)) do %>
<div class="box">
<header class="border-b pb-4 mb-4">
<h3 class="font-bold text-primary uppercase"><%= t(".delete.box_title") %></h3>
</header>
<div class="prose dark:prose-invert">
<p><%= t(".delete.description", name: @account_user.name) %></p>
<%= button_to t(".delete.button"), member_path(@account_user), class: "button danger", method: :delete, data: { confirm: t(".confirmation_message", name: @account_user.name), turbo_confirm: t(".confirmation_message", name: @account_user.name) } %>
</div>
</div>
<% end %>
39 changes: 39 additions & 0 deletions app/views/accounts/members/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<% title t(".title") %>
<%= render(PageLayouts::Settings::Component.new(
title: t(".title"),
description: t(".description")
)) do %>
<div class="box">
<header class="border-b pb-4 mb-4">
<h3 class="font-bold text-primary uppercase"><%= t(".box_title", team_name: @account.name) %></h3>
</header>

<div class="prose">
<table class="kiqr-table">
<thead>
<tr>
<th><%= t(".table.name") %></th>
<th><%= t(".table.email") %></th>
<th><%= t(".table.role") %></th>
<th class="text-right"><%= t(".table.actions") %></th>
</tr>
</thead>
<tbody>
<% @members.each do |member| %>
<tr>
<td><%= member.user.name %></td>
<td><%= member.user.email %></td>
<td><%= member.role %></td>
<td class="text-right">
<%= link_to t(".table.edit"), edit_member_path(id: member), class: "button xs" %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<div class="mt-6 flex justify-between items-center">
<%= link_to "Invite a new member", "#", class: "button" %>
</div>
<% end %>
12 changes: 11 additions & 1 deletion app/views/partials/navigations/_settings.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@
<%= render(PageLayouts::Settings::NavigationItem::Component.new(
label: t('.items.account.label'),
description: t('.items.account.description'),
icon: Current.account.personal? ? "fa fa-user" : "fa fa-users",
icon: "fa fa-id-card-clip",
path: edit_account_path
)) %>

<% unless current_account.personal? %>
<%= render(PageLayouts::Settings::NavigationItem::Component.new(
label: t('.items.members.label'),
description: t('.items.members.description'),
icon: "fa fa-users",
path: members_path,
active: current_base_path?(members_path)
)) %>
<% end %>

<div class="flex items-center justify-between bg-surface-hover py-3 px-4 text-sm font-bold border-y">
<%= t(".user_settings") %>
<i class="fa fa-arrow-turn-down w-3 h-3"></i>
Expand Down
1 change: 1 addition & 0 deletions config/credentials.yml.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
68f1lAzRuHJdsoUn+xOP1qA4uyyweYvYpC1fQbf8VwkrefELEgzEn8odaMSSRmnaFwd3vnJb5OQmxCcZCFEWnDaIp8wO+8K5SS/veymXozbnwf2i8PuWgHhZF/+M5wHa445hCjfyE8Br0OA1Z8uc+GHE7GJesJUAtIeHkxhRKbikRVepQAVdfDQNDI903ufKtK/Ws5CEZwe1SDb8Vss/whidT1DG7Br2i7F99VN9q4fsWIWih/qs6w3yt8fJNJQXFxsC/l+SWK/3uVAGVrbxah1I2vIA14SsC7aU3ruEw0WgYLKH1fIkDiePptlQUgTLaug23mZwSmybTwTcMjZoExBfYyf1Y52iqhg1ASLx1j0M/5R2Y9ho3X6q9RWLK/g48ZejznyT7/iqrfDWMryYwTrkEMccYLNn3jAn6CZJcSGMQPQARp216DlnCSyD9p0Xdqx37xC2pl4GP5BSHxXMb9B0kBICXqnKBND1VtQVwnuGxEj0aYK8d8GNl4ZqQ2dC4IBeTQgcyQ0a4r4A1t+8NPTmn1tYN8PY1sEIN92P45pNnknpi9SZSPqdtT/QLLxnIJJrL7XTlybV/grIYaDC9F15uCNMEGbDcxoXwvuZ3mo29tIeklVgT6HbLI1qAsG2MuHTClknitxPJDFMcxtlauTO75I/luk2g7si5lauXC8uYox8q5jgPj9z27RYSpXQ5+VJe0L13lUhoWfoW/mS0wVjVRe4sdWkLjJDZ0UH86UDd7Q1VbV0hr+ClEKWJQdxCid4GOHOs9D7bwICpPsgRQTMahDqWlaN6vtmBL1DfsTkj+kkmJPEpWG8/Eio94YgqHujOynU90e+fv6X8FDQ87vtjgrLPTELB4qUvB0WwaP7u/8sJX+Qa3UqcF3Jp35atobXTT/lKYCrS1EshFR9eGouvV4ZUr2YiP0ULAReZFAQbfVKm0o=--BLJ94eO0gaHIPwVS--+WUWE/M4QuFW6XeFxwrQAg==
35 changes: 34 additions & 1 deletion config/locales/kiqr.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ en:
user_settings: "Your personal settings"
items:
account:
label: "Profile settings"
label: "Profile"
description: "Edit your account profile"
members:
label: "Team members"
description: "Manage team members"
user:
label: "Login credentials"
description: "Change user email or password"
Expand Down Expand Up @@ -48,6 +51,36 @@ en:
button:
save: "Save changes"
create: "Create new account"
members:
index:
title: "Team members"
description: "Manage team members."
box_title: "Members of %{team_name}"
table:
name: "Name"
email: "Email"
role: "Role"
actions: "Actions"
edit: "Edit"
edit:
title: "Edit team member"
description: "Change settings for a team member."
box_title: "Edit team member: %{name}"
confirmation_message: "Are you sure you want to REMOVE %{name} from the team?"
delete:
box_title: "Remove team member"
description: "Remove %{name} from the team. They will no longer have access to the team account, but you can always invite them back later."
button: "Remove team member"
form:
submit: "Save changes"
account_users:
roles:
owner: "Owner"
admin: "Admin"
readonly: "Read-Only"
destroy:
success: "Member has successfully been removed from the team."
failure: "Member could not be removed. Please contact support if this issue persists."
users:
sessions:
new:
Expand Down
1 change: 1 addition & 0 deletions config/routes/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@

scope "(/team/:account_id)", account_id: %r{[^/]+} do
resource :account, only: [:edit, :update], path: "profile"
resources :members, controller: "accounts/members", only: [:index, :edit, :update, :destroy]
end
6 changes: 6 additions & 0 deletions db/migrate/20240404092246_add_public_uid_to_account_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddPublicUidToAccountUsers < ActiveRecord::Migration[7.1]
def change
add_column :account_users, :public_uid, :string
add_index :account_users, :public_uid, unique: true
end
end
4 changes: 3 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions test/controllers/accounts/members_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require "test_helper"

class Accounts::MembersControllerTest < ActionDispatch::IntegrationTest
test "can't show members as personal account" do
user = create(:user)
sign_in user
get members_path

assert_redirected_to edit_account_path(account_id: nil)
end

test "can show members as team account" do
user = create(:user)
account = create(:account, name: "Team account")
account.account_users << AccountUser.create(user:, role: "owner")

sign_in user
get members_path(account_id: account)

assert_response :success
end

test "can remove a member from team" do
user = create(:user)
some_user = create(:user)

account = create(:account, name: "Team account")
account.account_users << AccountUser.create(user: user, role: "owner")
account.account_users << AccountUser.create(user: some_user, role: "admin")

assert_includes account.reload.users, some_user

sign_in user
delete member_path(account_id: account, id: some_user.account_users.first)

assert_redirected_to members_path(account_id: account)
assert_not_includes account.reload.users, some_user
end

test "can not remove the team owner" do
skip "This test is not implemented yet"
end
end
2 changes: 1 addition & 1 deletion test/factories/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
password { "th1s1sp4ssw0rd" }
password_confirmation { "th1s1sp4ssw0rd" }
confirmed_at { Time.zone.now }
personal_account { build(:account) }
personal_account { build(:account, personal: true) }

trait :unconfirmed do
confirmed_at { nil }
Expand Down
6 changes: 3 additions & 3 deletions test/models/account_user_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "test_helper"

class AccountUserTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
test "should have the owner role" do
assert_includes AccountUser::ROLES, "owner"
end
end

0 comments on commit aa1090e

Please sign in to comment.