Skip to content

Commit

Permalink
Misc (#74)
Browse files Browse the repository at this point in the history
* Creating a rake task to onboard new customers

* Creating a rake task to onboard new customers

* owner and organization admin can manage their organization

* Update gems

* Event Policy

* Rolling back to appmap 0.99.1 as 0.99.3 creates routing issues

* EventPolicy

* Better Policy around User Management

* Better presentation of the roles

* Organiztion and User policies

* Adding a SettingsPolicy

* Better welcome screen

* Copy TXT record and some explanations for non tech users

* Adding Manage Polls to navbar

* Code optimization and query optimization

* Better poll display

* Gem updates

---------

Co-authored-by: Stephane Paquet <spaquet@up4b.com>
  • Loading branch information
spaquet and Stephane Paquet authored May 12, 2023
1 parent a101935 commit 1ee3af5
Show file tree
Hide file tree
Showing 28 changed files with 347 additions and 69 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ruby '3.2.2'
# IMPORTANT: This must be the first gem listed
# Add support to appmap in development and test

gem 'appmap', '~> 0.99.1', :groups => [:development, :test]
gem 'appmap', '0.99.1', :groups => [:development, :test]

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem 'rails', '~> 7.0.4'
Expand Down
20 changes: 10 additions & 10 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ GEM
ffi-compiler (~> 1.0)
ast (2.4.2)
aws-eventstream (1.2.0)
aws-partitions (1.761.0)
aws-partitions (1.763.0)
aws-sdk-core (3.172.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
Expand All @@ -121,7 +121,7 @@ GEM
bullet (7.0.7)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
capybara (3.39.0)
capybara (3.39.1)
addressable
matrix
mini_mime (>= 0.1.3)
Expand Down Expand Up @@ -204,9 +204,9 @@ GEM
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
loofah (2.20.0)
loofah (2.21.2)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
nokogiri (>= 1.12.0)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
Expand Down Expand Up @@ -234,11 +234,11 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.9)
nokogiri (1.14.3-arm64-darwin)
nokogiri (1.14.4-arm64-darwin)
racc (~> 1.4)
nokogiri (1.14.3-x86_64-linux)
nokogiri (1.14.4-x86_64-linux)
racc (~> 1.4)
noticed (1.6.2)
noticed (1.6.3)
http (>= 4.0.0)
rails (>= 5.2.0)
oauth2 (2.0.9)
Expand Down Expand Up @@ -385,7 +385,7 @@ GEM
sprockets (>= 3.0.0)
stimulus-rails (1.2.1)
railties (>= 6.0.0)
thor (1.2.1)
thor (1.2.2)
timeout (0.3.2)
turbo-rails (1.4.0)
actionpack (>= 6.0.0)
Expand Down Expand Up @@ -434,7 +434,7 @@ DEPENDENCIES
active_storage_validations (~> 1.0.0)
ahoy_matey
annotate (~> 3.2.0)
appmap (~> 0.99.1)
appmap (= 0.99.1)
argon2 (~> 2.2.0)
aws-sdk-s3
bootsnap
Expand Down Expand Up @@ -492,4 +492,4 @@ RUBY VERSION
ruby 3.2.2p53

BUNDLED WITH
2.4.12
2.4.13
16 changes: 14 additions & 2 deletions app/controllers/concerns/user_bulk_actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#
module UserBulkActions
extend ActiveSupport::Concern
include Pundit

# PATCH accounts/
# Used to update a bulk of users all at once.
Expand All @@ -14,6 +15,8 @@ module UserBulkActions
# - Promote Admin (assign as organization admin)
# - Demote Admin (remove from organization admin)
def bulk_update
authorize current_user, :bulk_update?

# Return if no user is selected
# if params[:user_ids].nil?
# logger.debug "WE HAVE NO USER SELECTED!!!"
Expand Down Expand Up @@ -60,7 +63,11 @@ def bulk_update
# Returns the number of modified objects.
def bulk_promote(user_ids)
logger.debug "MAKE ADMIN"
# Implementation code here
users = User.where(id: params.fetch(:user_ids, []).compact)
organization = current_user.organization
users.each do |user|
user.add_role(:admin, organization) if !user.has_role?(:admin, organization)
end
end

# Private: Demotes an array of organization admins to regular users.
Expand All @@ -74,7 +81,12 @@ def bulk_promote(user_ids)
#
# Returns the number of modified objects.
def bulk_demote(user_ids)
# Implementation code here
logger.debug "NO LONGER AN ADMIN"
users = User.where(id: params.fetch(:user_ids, []).compact)
organization = current_user.organization
users.each do |user|
user.remove_role(:admin, organization) if user.has_role?(:admin, organization)
end
end

# Private: Blocks an array of users.
Expand Down
16 changes: 11 additions & 5 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
class EventsController < ApplicationController
before_action :authenticate_user!, only: %i[index edit destroy update new]
before_action :redirect_if_unauthenticated, only: %i[index edit destroy update new]
before_action :set_event, except: %i[index new create event validate_pin]
before_action :authorize_event, only: [:show, :edit, :update, :stats, :export]

def index
@events = Event.where(user_id: current_user.id).order(start_date: :desc)
@events = policy_scope(Event).includes(user: :profile).order(start_date: :desc)
end

def new
Expand Down Expand Up @@ -49,18 +51,15 @@ def create
end

def show
@event = Event.find_by(id: params[:id])
@event.start_date = @event.start_date.strftime("%m/%d/%Y")
end

def edit
@event = Event.find_by(id: params[:id])
@event.start_date = @event.start_date.strftime("%m/%d/%Y")
end

# GET /event/:id/stats
def stats
@event = Event.find_by(id: params[:id])
@questions = Question.where(room_id: @event.rooms.first.id).order(status: :desc).order(created_at: :desc)
@count = @questions.count
if @count > 0
Expand Down Expand Up @@ -124,7 +123,6 @@ def event

# GET /event/:id/export
def export
@event = Event.find(params[:id])
@room = @event.rooms.first

@questions = Question.where(room_id: @room.id)
Expand Down Expand Up @@ -181,6 +179,14 @@ def destroy

private

def set_event
@event = Event.find(params[:id])
end

def authorize_event
authorize @event
end

def create_event_params
params.require(:event).permit(:allow_anonymous, :always_on, :description, :event_type, :name, :start_date, :status, :stop_date)
end
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/organization_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class OrganizationController < ApplicationController
before_action :authenticate_user!
before_action :redirect_if_unauthenticated
before_action :set_organization
before_action :authorize_organization, only: [:show, :edit, :update]

# DELETE /organization/:id
def destroy
Expand Down Expand Up @@ -47,4 +48,8 @@ def update_organization_params
def set_organization
@organization = Organization.find(params[:id])
end

def authorize_organization
authorize @organization
end
end
20 changes: 12 additions & 8 deletions app/controllers/settings_controller.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
class SettingsController < ApplicationController
before_action :authenticate_user!
before_action :redirect_if_unauthenticated
before_action :set_organization_and_authorize

layout "settings"

# GET /settings/
def index
# TODO add a condition for when a user is an admin for the account. so that extraction of the organization will be something like current_user.member.organization
# TODO add a second condition owner: true
# Current code only displays account information when the user is the owner
organization = Member.find_by(user_id: current_user.id, owner: true).organization
if organization
@organization_id = organization.id
@user_count = organization.members.count
@organization_owner = true
if @organization
@organization_id = @organization.id
@user_count = @organization.members.count
@organization_owner = current_user.member.owner?
else
flash[:alert] = "You are not the owner of this organization"
redirect_to root_path
end
end

private

def set_organization_and_authorize
@organization = current_user.organization
authorize @organization, :index?, policy_class: SettingsPolicy
end
end
9 changes: 7 additions & 2 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class UsersController < ApplicationController
# GET /organization/:id/users
def index
@organization = Organization.find(params[:organization_id])
authorize @organization, :manage_users?
@users = @organization.users.includes([:profile, :organization])
end

Expand Down Expand Up @@ -47,6 +48,7 @@ def destroy
# Used by admin or organization owner to delete a user
def delete_user
@user = User.find(params[:id])
authorize @user

if @user && !is_organization_owner?
# Disconnect the user from all previous session
Expand Down Expand Up @@ -149,15 +151,17 @@ def resend_confirmation
# Method used to resend an invitation to join an organization to a user.
def resend_invite
@user = User.find(params[:id])
authorize @user
if @user && @user.invited && @user.accepted_invitation_on.nil?
@user.send_invite!
end
end

# Method used to toggle the blocked value for a given user
def block
# TODO make sure that only the admin or the owner of an organization can use this
@user = User.find(params[:id])
authorize @user

if @user
if @user.blocked
@user.unblock!
Expand All @@ -171,8 +175,9 @@ def block

# Method used by an admin or organization owner to reset the unlocked a given user
def unlock
# TODO make sure that only the admin or the owner of an organization can use this
@user = User.find(params[:id])
authorize @user

if @user
if @user.locked
@user.unlock!
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ def flash_text_color(type)
'text-green-700'
end
end

def admin_or_owner?(user)
user.organization_owner?(user.organization) || user.has_role?(:admin, user.organization)
end
end
3 changes: 2 additions & 1 deletion app/helpers/events_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module EventsHelper

def event_creator(event)
if user_signed_in? && event.user_id == Current.user.id
# if user_signed_in? && event.user_id == Current.user.id
if event.user_id == Current.user.id
'you'
else
event.user.profile.nickname.strip
Expand Down
5 changes: 4 additions & 1 deletion app/helpers/users_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ def user_status(user)
def user_roles(user)
member = Member.find_by(user_id: user.id, organization: user.organization.id)
if member.owner
return '<span class="bg-blue-100 text-blue-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full dark:bg-blue-900 dark:text-blue-300">Owner</span>'.html_safe
return '<span class="bg-purple-100 text-purple-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full dark:bg-purple-900 dark:text-purple-300">Owner</span>'.html_safe
end
if user.has_role?(:admin, user.organization)
return '<span class="bg-blue-100 text-blue-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full dark:bg-blue-900 dark:text-blue-300">Admin</span>'.html_safe
end
end
end
41 changes: 21 additions & 20 deletions app/javascript/controllers/poll_chart_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,50 @@ export default class extends Controller {
};

connect() {
// Set up the chart
// Create the chart and displays it
this.chart = new Chart(this.chartTarget, {
plugins: [ChartDataLabels],
type: "bar",
data: {
labels: this.labelsValue,
datasets: [
{
backgroundColor: "rgba(79, 70, 229, 1)",
backgroundColor: "rgba(79, 70, 229, 0.4)",
borderColor: "rgba(79, 70, 229, 1)",
data: this.dataValue,
borderWidth: 0,
borderWidth: 1,
borderSkipped: false,
borderRadius: 5,
barPercentage: 1,
categoryPercentage: 0.5,
},
],
},
plugins: [ChartDataLabels],
options: {
events: [],
indexAxis: "y", // To have horizontal bars
scales: {
x: {
grid: {
display: false,
drawBorder: false,
},
ticks: { display: false },
},
},
plugins: {
legend: {
display: false,
},
datalabels: {
display: true,
align: "start",
anchor: "start",
offset: 5,
color: "#000", // Choose the color you want for the labels
// formatter: function (value, context) {
// return value; // Display the data value as-is
// },
y: {
grid: {
display: false,
drawBorder: false,
},
ticks: { display: false },
},
},
title: {
display: false,
plugins: {
legend: { display: false },
tooltip: { enabled: false },
hover: { mode: null },
},
title: { display: false },
responsive: true,
},
});
Expand Down
1 change: 1 addition & 0 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Event < ApplicationRecord
before_validation :set_values

belongs_to :user
belongs_to :organization
has_many :attendances, dependent: :destroy
has_many :rooms, dependent: :destroy

Expand Down
1 change: 1 addition & 0 deletions app/models/organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Organization < ApplicationRecord
has_many :members
has_many :users, through: :members
has_many :polls, dependent: :destroy
has_many :events, dependent: :destroy

has_one_attached :logo

Expand Down
Loading

0 comments on commit 1ee3af5

Please sign in to comment.