simple_teams 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/simple_teams_manifest.js +1 -0
- data/app/assets/stylesheets/simple_teams/application.css +15 -0
- data/app/controllers/simple_teams/accept_invitations_controller.rb +57 -0
- data/app/controllers/simple_teams/admin/invitations_controller.rb +60 -0
- data/app/controllers/simple_teams/admin/memberships_controller.rb +60 -0
- data/app/controllers/simple_teams/admin/teams_controller.rb +60 -0
- data/app/controllers/simple_teams/application_controller.rb +13 -0
- data/app/controllers/simple_teams/invitations_controller.rb +96 -0
- data/app/controllers/simple_teams/leave_teams_controller.rb +25 -0
- data/app/controllers/simple_teams/memberships_controller.rb +61 -0
- data/app/controllers/simple_teams/related_members_controller.rb +33 -0
- data/app/controllers/simple_teams/teams_controller.rb +19 -0
- data/app/forms/simple_teams/invitation_form.rb +77 -0
- data/app/forms/simple_teams/invitation_forms/create.rb +24 -0
- data/app/forms/simple_teams/invitation_forms/create_bulk.rb +125 -0
- data/app/forms/simple_teams/invitation_forms/create_combo.rb +75 -0
- data/app/forms/simple_teams/invitation_forms/update.rb +29 -0
- data/app/forms/simple_teams/membership_form.rb +91 -0
- data/app/helpers/simple_teams/application_helper.rb +4 -0
- data/app/helpers/simple_teams/invitations_helper.rb +4 -0
- data/app/helpers/simple_teams/memberships_helper.rb +4 -0
- data/app/helpers/simple_teams/teams_helper.rb +4 -0
- data/app/jobs/simple_teams/application_job.rb +4 -0
- data/app/mailers/simple_teams/application_mailer.rb +6 -0
- data/app/mailers/simple_teams/mailer.rb +17 -0
- data/app/models/concerns/simple_teams/member_object.rb +22 -0
- data/app/models/concerns/simple_teams/team_object.rb +23 -0
- data/app/models/simple_teams/ability.rb +34 -0
- data/app/models/simple_teams/application_record.rb +5 -0
- data/app/models/simple_teams/invitation.rb +85 -0
- data/app/models/simple_teams/membership.rb +16 -0
- data/app/models/simple_teams/team.rb +23 -0
- data/app/notifications/application_notification.rb +4 -0
- data/app/notifications/simple_teams/bulk_invitations_notification.rb +51 -0
- data/app/notifications/simple_teams/invitation_notification.rb +54 -0
- data/app/notifications/simple_teams/invitations/accepted_notification.rb +13 -0
- data/app/notifications/simple_teams/invitations/created_notification.rb +13 -0
- data/app/notifications/simple_teams/invitations/destroyed_notification.rb +13 -0
- data/app/notifications/simple_teams/invitations/updated_notification.rb +13 -0
- data/app/notifications/simple_teams/membership_notification.rb +58 -0
- data/app/notifications/simple_teams/memberships/destroyed_notification.rb +13 -0
- data/app/notifications/simple_teams/memberships/left_notification.rb +17 -0
- data/app/notifications/simple_teams/memberships/updated_notification.rb +17 -0
- data/app/service_objects/simple_teams/accept_invitation_service.rb +61 -0
- data/app/service_objects/simple_teams/initialize_team_service.rb +25 -0
- data/app/service_objects/simple_teams/leave_team_service.rb +56 -0
- data/app/views/layouts/simple_teams/application.html.erb +20 -0
- data/app/views/simple_teams/_roles_field.html.erb +22 -0
- data/app/views/simple_teams/accept_invitations/invalid_token.html.erb +7 -0
- data/app/views/simple_teams/accept_invitations/new.html.erb +18 -0
- data/app/views/simple_teams/admin/invitations/_form.html.erb +62 -0
- data/app/views/simple_teams/admin/invitations/_invitation.html.erb +47 -0
- data/app/views/simple_teams/admin/invitations/edit.html.erb +10 -0
- data/app/views/simple_teams/admin/invitations/index.html.erb +14 -0
- data/app/views/simple_teams/admin/invitations/new.html.erb +9 -0
- data/app/views/simple_teams/admin/invitations/show.html.erb +10 -0
- data/app/views/simple_teams/admin/memberships/_form.html.erb +32 -0
- data/app/views/simple_teams/admin/memberships/_membership.html.erb +17 -0
- data/app/views/simple_teams/admin/memberships/edit.html.erb +10 -0
- data/app/views/simple_teams/admin/memberships/index.html.erb +14 -0
- data/app/views/simple_teams/admin/memberships/new.html.erb +9 -0
- data/app/views/simple_teams/admin/memberships/show.html.erb +10 -0
- data/app/views/simple_teams/admin/teams/_form.html.erb +22 -0
- data/app/views/simple_teams/admin/teams/_team.html.erb +7 -0
- data/app/views/simple_teams/admin/teams/edit.html.erb +10 -0
- data/app/views/simple_teams/admin/teams/index.html.erb +14 -0
- data/app/views/simple_teams/admin/teams/new.html.erb +9 -0
- data/app/views/simple_teams/admin/teams/show.html.erb +10 -0
- data/app/views/simple_teams/invitations/_bulk_form.html.erb +63 -0
- data/app/views/simple_teams/invitations/_form.html.erb +15 -0
- data/app/views/simple_teams/invitations/_invitation.html.erb +19 -0
- data/app/views/simple_teams/invitations/_invitation.json.jbuilder +2 -0
- data/app/views/simple_teams/invitations/edit.html.erb +12 -0
- data/app/views/simple_teams/invitations/new.html.erb +12 -0
- data/app/views/simple_teams/leave_teams/edit.html.erb +2 -0
- data/app/views/simple_teams/memberships/_form.html.erb +12 -0
- data/app/views/simple_teams/memberships/_membership.html.erb +23 -0
- data/app/views/simple_teams/memberships/edit.html.erb +12 -0
- data/app/views/simple_teams/related_members/index.json.jbuilder +5 -0
- data/app/views/simple_teams/related_members/select2.json.jbuilder +6 -0
- data/app/views/simple_teams/teams/_add_member_link.html.erb +3 -0
- data/app/views/simple_teams/teams/_members_table.html.erb +20 -0
- data/app/views/simple_teams/teams/show.html.erb +38 -0
- data/app/views/simple_teams/teams_mailer/invitation_notification.html.erb +9 -0
- data/config/locales/simple_teams.en.yml +18 -0
- data/config/routes.rb +21 -0
- data/db/migrate/20240311052758_create_simple_teams_teams.rb +9 -0
- data/db/migrate/20240311053006_create_simple_teams_memberships.rb +11 -0
- data/db/migrate/20240311053607_create_simple_teams_invitations.rb +17 -0
- data/lib/simple_teams/engine.rb +22 -0
- data/lib/simple_teams/version.rb +3 -0
- data/lib/simple_teams.rb +6 -0
- data/lib/tasks/simple_teams_tasks.rake +4 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7f626da6c44a20f9b042cea11e321034ddaea542c5a96504017c309850d67bdb
|
4
|
+
data.tar.gz: 5c8bc35a2bbd95fc017ce9e427197cc962bb7118096de9675ca8980cfec0d79c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7012cf09146fa7e7f5c2b86835baf11db9a72d26194cc1125021980aa65567d66fd56a37e7d668634a9989e3665fddad1ea773d1572f37e8a110d50cf8d8c872
|
7
|
+
data.tar.gz: 4e69cb8dab76dc70b37171e043d89c877daa75d2389c2757a62e85311d6143b8df3d85a6164a232550b368bc46b95979ca625147be109d249d7f9df0e1dd0fe2
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2024 Laney Stroup
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# SimpleTeams
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "simple_teams"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install simple_teams
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/simple_teams .css
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class AcceptInvitationsController < ApplicationController
|
3
|
+
skip_before_action :authenticate_user!
|
4
|
+
before_action :set_invitation
|
5
|
+
before_action :ensure_invitation_token_is_valid
|
6
|
+
before_action :set_team
|
7
|
+
before_action :set_service_object
|
8
|
+
|
9
|
+
def new
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
if params[:commit] == "Decline"
|
14
|
+
@invitation.declined!
|
15
|
+
redirect_to root_path, :notice => "You have declined the invitation to the '#{@team.name}' #{@team.teamable.class.model_name.human}."
|
16
|
+
else
|
17
|
+
if @service_object.valid?
|
18
|
+
@service_object.perform
|
19
|
+
|
20
|
+
SimpleTeams::Invitations::AcceptedNotification.with(
|
21
|
+
:team_id => @team.id,
|
22
|
+
:invitation_id => @invitation.id,
|
23
|
+
:user_id => current_user.id,
|
24
|
+
:team_name => @team.name,
|
25
|
+
:invitation_name => @invitation.email,
|
26
|
+
:user_name => current_user.full_name
|
27
|
+
).deliver_later(@team.members)
|
28
|
+
|
29
|
+
redirect_to url_for(@team.teamable), :notice => "You have accepted the invitation to the '#{@team.name}' #{@team.teamable.class.model_name.human}."
|
30
|
+
else
|
31
|
+
render :new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def set_invitation
|
39
|
+
@invitation = SimpleTeams::Invitation.initial.unexpired.find_by(token: params[:id])
|
40
|
+
end
|
41
|
+
|
42
|
+
def ensure_invitation_token_is_valid
|
43
|
+
unless @invitation.present?
|
44
|
+
render "invalid_token"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_team
|
49
|
+
@team = @invitation.team
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_service_object
|
53
|
+
@service_object = SimpleTeams::AcceptInvitationService.new(current_user.id, @invitation.token)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class InvitationsController < ApplicationController
|
3
|
+
before_action :set_invitation, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /invitations
|
6
|
+
def index
|
7
|
+
@invitations = Invitation.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /invitations/1
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /invitations/new
|
15
|
+
def new
|
16
|
+
@invitation = Invitation.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /invitations/1/edit
|
20
|
+
def edit
|
21
|
+
end
|
22
|
+
|
23
|
+
# POST /invitations
|
24
|
+
def create
|
25
|
+
@invitation = Invitation.new(invitation_params)
|
26
|
+
|
27
|
+
if @invitation.save
|
28
|
+
redirect_to @invitation, notice: "Invitation was successfully created."
|
29
|
+
else
|
30
|
+
render :new, status: :unprocessable_entity
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# PATCH/PUT /invitations/1
|
35
|
+
def update
|
36
|
+
if @invitation.update(invitation_params)
|
37
|
+
redirect_to @invitation, notice: "Invitation was successfully updated.", status: :see_other
|
38
|
+
else
|
39
|
+
render :edit, status: :unprocessable_entity
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE /invitations/1
|
44
|
+
def destroy
|
45
|
+
@invitation.destroy
|
46
|
+
redirect_to invitations_url, notice: "Invitation was successfully destroyed.", status: :see_other
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
# Use callbacks to share common setup or constraints between actions.
|
51
|
+
def set_invitation
|
52
|
+
@invitation = Invitation.find(params[:id])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Only allow a list of trusted parameters through.
|
56
|
+
def invitation_params
|
57
|
+
params.require(:invitation).permit(:team_id, :inviter_id, :membership_id, :email, :role, :token, :status, :sent_at, :expires_at)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class MembershipsController < ApplicationController
|
3
|
+
before_action :set_membership, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /memberships
|
6
|
+
def index
|
7
|
+
@memberships = Membership.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /memberships/1
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /memberships/new
|
15
|
+
def new
|
16
|
+
@membership = Membership.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /memberships/1/edit
|
20
|
+
def edit
|
21
|
+
end
|
22
|
+
|
23
|
+
# POST /memberships
|
24
|
+
def create
|
25
|
+
@membership = Membership.new(membership_params)
|
26
|
+
|
27
|
+
if @membership.save
|
28
|
+
redirect_to @membership, notice: "Membership was successfully created."
|
29
|
+
else
|
30
|
+
render :new, status: :unprocessable_entity
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# PATCH/PUT /memberships/1
|
35
|
+
def update
|
36
|
+
if @membership.update(membership_params)
|
37
|
+
redirect_to @membership, notice: "Membership was successfully updated.", status: :see_other
|
38
|
+
else
|
39
|
+
render :edit, status: :unprocessable_entity
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE /memberships/1
|
44
|
+
def destroy
|
45
|
+
@membership.destroy
|
46
|
+
redirect_to memberships_url, notice: "Membership was successfully destroyed.", status: :see_other
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
# Use callbacks to share common setup or constraints between actions.
|
51
|
+
def set_membership
|
52
|
+
@membership = Membership.find(params[:id])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Only allow a list of trusted parameters through.
|
56
|
+
def membership_params
|
57
|
+
params.require(:membership).permit(:team_id, :member_id, :role)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class TeamsController < ApplicationController
|
3
|
+
before_action :set_team, only: %i[ show edit update destroy ]
|
4
|
+
|
5
|
+
# GET /teams
|
6
|
+
def index
|
7
|
+
@teams = Team.all
|
8
|
+
end
|
9
|
+
|
10
|
+
# GET /teams/1
|
11
|
+
def show
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /teams/new
|
15
|
+
def new
|
16
|
+
@team = Team.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /teams/1/edit
|
20
|
+
def edit
|
21
|
+
end
|
22
|
+
|
23
|
+
# POST /teams
|
24
|
+
def create
|
25
|
+
@team = Team.new(team_params)
|
26
|
+
|
27
|
+
if @team.save
|
28
|
+
redirect_to @team, notice: "Team was successfully created."
|
29
|
+
else
|
30
|
+
render :new, status: :unprocessable_entity
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# PATCH/PUT /teams/1
|
35
|
+
def update
|
36
|
+
if @team.update(team_params)
|
37
|
+
redirect_to @team, notice: "Team was successfully updated.", status: :see_other
|
38
|
+
else
|
39
|
+
render :edit, status: :unprocessable_entity
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# DELETE /teams/1
|
44
|
+
def destroy
|
45
|
+
@team.destroy
|
46
|
+
redirect_to teams_url, notice: "Team was successfully destroyed.", status: :see_other
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
# Use callbacks to share common setup or constraints between actions.
|
51
|
+
def set_team
|
52
|
+
@team = Team.find(params[:id])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Only allow a list of trusted parameters through.
|
56
|
+
def team_params
|
57
|
+
params.require(:team).permit(:teamable_id, :teamable_type)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class ApplicationController < SimpleTeams.parent_controller
|
3
|
+
before_action :authenticate_user!
|
4
|
+
|
5
|
+
layout SimpleTeams.layout
|
6
|
+
|
7
|
+
def current_ability
|
8
|
+
SimpleTeams::Ability.new(current_user)
|
9
|
+
end
|
10
|
+
helper_method :current_ability
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class InvitationsController < ApplicationController
|
3
|
+
before_action :set_team
|
4
|
+
before_action :set_invitation, except: %i[ new create index]
|
5
|
+
|
6
|
+
def new
|
7
|
+
authorize! :create, @team.invitations.new
|
8
|
+
@service_object = SimpleTeams::InvitationForms::CreateCombo.new(@team, current_user)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
authorize! :create, @team.invitations.new
|
13
|
+
@service_object = SimpleTeams::InvitationForms::CreateCombo.new(@team, current_user)
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
if @service_object.perform(new_service_object_params)
|
17
|
+
format.html { redirect_to team_path(@team), notice: "Invitations were successfully created." }
|
18
|
+
format.json { render :show, status: :created, location: @invitation }
|
19
|
+
else
|
20
|
+
format.html { render :new, status: :unprocessable_entity }
|
21
|
+
format.json { render json: @invitation.errors, status: :unprocessable_entity }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit
|
27
|
+
authorize! :update, @invitation
|
28
|
+
@service_object = SimpleTeams::InvitationForms::Update.new(@invitation, current_user)
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
authorize! :update, @invitation
|
33
|
+
@service_object = SimpleTeams::InvitationForms::Update.new(@invitation, current_user)
|
34
|
+
|
35
|
+
respond_to do |format|
|
36
|
+
if @service_object.perform(service_object_params)
|
37
|
+
format.html { redirect_to team_path(@team), notice: "Invitation was successfully updated." }
|
38
|
+
format.json { head :no_content }
|
39
|
+
else
|
40
|
+
format.html { render :edit, status: :unprocessable_entity }
|
41
|
+
format.json { render json: @invitation.errors, status: :unprocessable_entity }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def resend
|
48
|
+
authorize! :update, @invitation
|
49
|
+
@invitation.resend_invitation_notification
|
50
|
+
|
51
|
+
respond_to do |format|
|
52
|
+
format.html { redirect_to team_path(@team), notice: "Invitation was successfully resent." }
|
53
|
+
format.json { head :no_content }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def destroy
|
58
|
+
authorize! :destroy, @invitation
|
59
|
+
invitation_id = @invitation.id
|
60
|
+
invitation_email = @invitation.email
|
61
|
+
@invitation.destroy
|
62
|
+
|
63
|
+
SimpleTeams::Invitations::DestroyedNotification.with(
|
64
|
+
:team_id => @team.id,
|
65
|
+
:invitation_id => invitation_id,
|
66
|
+
:user_id => current_user.id,
|
67
|
+
:team_name => @team.name,
|
68
|
+
:invitation_name => invitation_email,
|
69
|
+
:user_name => current_user.full_name
|
70
|
+
).deliver_later(@team.members)
|
71
|
+
|
72
|
+
respond_to do |format|
|
73
|
+
format.html { redirect_to team_path(@team), notice: "Invitation was successfully destroyed." }
|
74
|
+
format.json { head :no_content }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def new_service_object_params
|
81
|
+
params.require(:invitation_forms_create_combo).permit(:role, :single_vs_multiple, :email, :accessible_emails, :select2_emails => [])
|
82
|
+
end
|
83
|
+
|
84
|
+
def service_object_params
|
85
|
+
params.require(:invitation_forms_update).permit(:email, :role)
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_team
|
89
|
+
@team = SimpleTeams::Team.find(params[:team_id])
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_invitation
|
93
|
+
@invitation = SimpleTeams::Invitation.find(params[:id])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class LeaveTeamsController < ApplicationController
|
3
|
+
before_action :set_team
|
4
|
+
before_action :set_service_object
|
5
|
+
|
6
|
+
def destroy
|
7
|
+
if @service_object.valid? and @service_object.perform
|
8
|
+
redirect_to root_path, :notice => "You have successfully left the #{@team.name} #{@team.teamable.class.model_name.human}."
|
9
|
+
else
|
10
|
+
redirect_to team_path(@team), :notice => @service_object.errors[:user_id].first
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def set_team
|
17
|
+
@team = SimpleTeams::Team.find(params[:team_id])
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_service_object
|
21
|
+
@service_object = SimpleTeams::LeaveTeamService.new(current_user.id, @team.id)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class MembershipsController < ApplicationController
|
3
|
+
before_action :set_team
|
4
|
+
before_action :set_membership, :except => [:index]
|
5
|
+
|
6
|
+
def edit
|
7
|
+
authorize! :edit, @membership
|
8
|
+
@service_object = SimpleTeams::MembershipForm.new(@membership, current_user)
|
9
|
+
end
|
10
|
+
|
11
|
+
def update
|
12
|
+
authorize! :edit, @membership
|
13
|
+
@service_object = SimpleTeams::MembershipForm.new(@membership, current_user)
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
if @service_object.perform(service_object_params)
|
17
|
+
format.html { redirect_to team_path(@team), notice: "Membership was updated successfully." }
|
18
|
+
format.json { render :show, status: :created, location: @service_object.membership }
|
19
|
+
else
|
20
|
+
format.html { render :edit, status: :unprocessable_entity }
|
21
|
+
format.json { render json: @service_object.errors, status: :unprocessable_entity }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def destroy
|
27
|
+
authorize! :destroy, @membership
|
28
|
+
|
29
|
+
member_id = @membership.member.id
|
30
|
+
member_name = @membership.member.full_name
|
31
|
+
recipients = @team.members.to_a
|
32
|
+
|
33
|
+
@membership.destroy
|
34
|
+
|
35
|
+
SimpleTeams::Memberships::DestroyedNotification.with(
|
36
|
+
:team_id => @team.id,
|
37
|
+
:member_id => member_id,
|
38
|
+
:user_id => current_user.id,
|
39
|
+
:team_name => @team.name,
|
40
|
+
:member_name => member_name,
|
41
|
+
:user_name => current_user.full_name
|
42
|
+
).deliver_later(recipients)
|
43
|
+
|
44
|
+
redirect_to team_path(@team)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def service_object_params
|
50
|
+
params.require(:teams_membership_form).permit(:role)
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_team
|
54
|
+
@team = SimpleTeams::Team.find(params[:team_id])
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_membership
|
58
|
+
@membership = @team.memberships.find(params[:id])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class RelatedUsersController < ApplicationController
|
3
|
+
|
4
|
+
def index
|
5
|
+
if params[:term].present?
|
6
|
+
@members = SimpleTeams.member_class
|
7
|
+
.joins(:team_memberships, :teams)
|
8
|
+
.where("teams_teams.id" => current_user.teams.pluck(:id))
|
9
|
+
.where("email ilike ?", "%#{params[:term]}%")
|
10
|
+
.order("#{SimpleTeams.member_class.table_name}.first_name")
|
11
|
+
.uniq
|
12
|
+
@members.reject! { |member| member.id == current_user.id }
|
13
|
+
else
|
14
|
+
@members= SimpleTeams.member_class.none
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def select2
|
19
|
+
if params[:term].present?
|
20
|
+
@members = SimpleTeams.member_class
|
21
|
+
.joins(:team_memberships, :teams)
|
22
|
+
.where("teams_teams.id" => current_user.teams.pluck(:id))
|
23
|
+
.where("email ilike ?", "%#{params[:term]}%")
|
24
|
+
.order("#{SimpleTeams.member_class.table_name}.first_name")
|
25
|
+
.uniq
|
26
|
+
@members.reject! { |member| member.id == current_user.id }
|
27
|
+
else
|
28
|
+
@members = SimpleTeams.member_class.none
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class TeamsController < ApplicationController
|
3
|
+
before_action :set_team
|
4
|
+
|
5
|
+
def show
|
6
|
+
authorize! :read, @team
|
7
|
+
@memberships = @team.memberships.joins(:member).order(:first_name)
|
8
|
+
@invitations = @team.invitations.initial.order(:email)
|
9
|
+
@memberships_and_invitations = @memberships.to_a + @invitations.to_a
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def set_team
|
15
|
+
@team = SimpleTeams::Team.find(params[:id])
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class InvitationForm < ApplicationForm
|
3
|
+
|
4
|
+
attr_accessor :team, :current_user, :invitation, :email, :role
|
5
|
+
|
6
|
+
def initialize(team, current_user)
|
7
|
+
raise NotImplementedError
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform(params)
|
11
|
+
self.assign_attributes(params)
|
12
|
+
|
13
|
+
if valid?
|
14
|
+
invitation.update!(params)
|
15
|
+
generate_notification
|
16
|
+
else
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Attributes
|
22
|
+
def self.invitation_attributes
|
23
|
+
[:email, :role]
|
24
|
+
end
|
25
|
+
|
26
|
+
def available_roles
|
27
|
+
@available_roles ||= SimpleTeams::Membership.roles
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def valid?
|
33
|
+
self.errors.clear
|
34
|
+
validate_role_is_available
|
35
|
+
validate_invitation
|
36
|
+
validate_current_user_has_rights_to_invite_an_owner
|
37
|
+
!self.errors.present?
|
38
|
+
end
|
39
|
+
|
40
|
+
def validate_role_is_available
|
41
|
+
# Note: Users will never see this error message unless they hack the form
|
42
|
+
if role.present?
|
43
|
+
unless available_roles.keys.include? role
|
44
|
+
self.errors.add(:role, "that role is not available for this resource")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def validate_invitation
|
50
|
+
# Update invitation object
|
51
|
+
self.class.invitation_attributes.each do |a|
|
52
|
+
invitation.assign_attributes(a => self.send(a))
|
53
|
+
end
|
54
|
+
|
55
|
+
# Call valid?
|
56
|
+
invitation.valid?
|
57
|
+
|
58
|
+
# Reassign errors
|
59
|
+
self.class.invitation_attributes.each do |a|
|
60
|
+
if invitation.errors[a].present?
|
61
|
+
invitation.errors[a].each do |e|
|
62
|
+
self.errors.add(a, e)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_current_user_has_rights_to_invite_an_owner
|
69
|
+
if role == "owner"
|
70
|
+
unless current_user.membership_for_team(team).owner?
|
71
|
+
self.errors.add(:role, "you must be an owner yourself to add add another owner")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module SimpleTeams
|
2
|
+
class InvitationForms::Create < SimpleTeams::InvitationForm
|
3
|
+
|
4
|
+
def initialize(team, current_user)
|
5
|
+
@team = team
|
6
|
+
@current_user = current_user
|
7
|
+
@invitation = team.invitations.new(:inviter => @current_user)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def generate_notification
|
13
|
+
SimpleTeams::Invitations::CreatedNotification.with(
|
14
|
+
:team_id => team.id,
|
15
|
+
:invitation_id => invitation.id,
|
16
|
+
:user_id => current_user.id,
|
17
|
+
:team_name => team.name,
|
18
|
+
:invitation_name => invitation.email,
|
19
|
+
:user_name => current_user.full_name
|
20
|
+
).deliver_later(team.members)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|