bullet_train 1.4.2 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/account/onboarding/invitation_lists_controller.rb +3 -0
- data/app/controllers/concerns/account/onboarding/invitation_lists/controller_base.rb +64 -0
- data/app/controllers/concerns/account/onboarding/user_details/controller_base.rb +7 -1
- data/app/controllers/concerns/account/users/controller_base.rb +11 -1
- data/app/helpers/account/onboarding/invitation_lists_helper.rb +9 -0
- data/app/models/account/onboarding/invitation_list.rb +7 -0
- data/app/models/concerns/account/onboarding/invitation_lists/base.rb +11 -0
- data/app/models/concerns/invitations/base.rb +1 -0
- data/app/views/account/onboarding/invitation_lists/_invitation_form.html.erb +11 -0
- data/app/views/account/onboarding/invitation_lists/new.html.erb +31 -0
- data/app/views/account/users/_form.html.erb +0 -4
- data/app/views/account/users/edit.html.erb +22 -5
- data/config/locales/en/onboarding/invitation_lists.en.yml +16 -0
- data/config/locales/en/users.en.yml +9 -5
- data/config/routes.rb +1 -0
- data/docs/field-partials/super-select.md +1 -1
- data/docs/upgrades/yolo-130.md +4 -4
- data/docs/upgrades/yolo-140.md +4 -4
- data/docs/upgrades.md +4 -2
- data/lib/bullet_train/configuration.rb +6 -1
- data/lib/bullet_train/resolver.rb +6 -2
- data/lib/bullet_train/version.rb +1 -1
- data/lib/bullet_train.rb +4 -0
- data/lib/tasks/bullet_train_tasks.rake +19 -9
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d073ab349f58c17453f4e4d3f493e97202a56a9c6d521bffe36109f4e78d63b
|
4
|
+
data.tar.gz: 870e67cb3d4b7562f3fb8faad380bc45d3b0866b9f51bedc808481db82ce61f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02a859e9c7b3be4b50ede0d7f45bf4fb53614953a5056bfc94511facb63179b56d4b8b94227fdce6bd23bf3af78d4e5d5ccc0d92c89abf6662a6c868f8c7a15d
|
7
|
+
data.tar.gz: 648560376f7307b66aa2eb52788c82278f5c277e8d34d22f6808d3053216634c5e482fd6b995102af9313c3aed123062764ca89c171eaa5b562475e2c42ec314
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Account::Onboarding::InvitationLists::ControllerBase
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
layout "devise"
|
6
|
+
|
7
|
+
before_action do
|
8
|
+
# TODO: Is this okay?
|
9
|
+
@user = current_user
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
@account_onboarding_invitation_list = Account::Onboarding::InvitationList.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def create
|
18
|
+
@account_onboarding_invitation_list = Account::Onboarding::InvitationList.new(account_onboarding_invitation_list_params)
|
19
|
+
|
20
|
+
# Set default values for invitations and memberships.
|
21
|
+
# `save` below checks if the values are valid or not.
|
22
|
+
@account_onboarding_invitation_list.team = current_team
|
23
|
+
@account_onboarding_invitation_list.invitations.each_with_index do |invitation, idx|
|
24
|
+
invitation.team = current_team
|
25
|
+
invitation.from_membership = current_membership
|
26
|
+
invitation.membership.team = current_team
|
27
|
+
invitation.membership.user_email = invitation.email
|
28
|
+
end
|
29
|
+
|
30
|
+
respond_to do |format|
|
31
|
+
if @account_onboarding_invitation_list.save
|
32
|
+
format.html { redirect_to account_team_path(@user.teams.first), notice: "" }
|
33
|
+
format.json { render :show, status: :ok, location: [:account, @user] }
|
34
|
+
else
|
35
|
+
format.html { render :new, status: :unprocessable_entity }
|
36
|
+
format.json { render json: @account_onboarding_invitation_list.errors, status: :unprocessable_entity }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
44
|
+
def account_onboarding_invitation_list_params
|
45
|
+
params.require(:account_onboarding_invitation_list).permit(
|
46
|
+
invitations_attributes: [
|
47
|
+
:email,
|
48
|
+
membership_attributes: [
|
49
|
+
role_ids: []
|
50
|
+
]
|
51
|
+
]
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def current_membership
|
56
|
+
current_user.memberships.find_by(team: current_team)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Since there is only one membership (an admin) on the team when sending bulk invitations,
|
60
|
+
# we don't have to worry about filtering these roles according to if they're manageable or not.
|
61
|
+
def available_roles
|
62
|
+
current_membership.roles.map { |role| [role.attributes[:key]] + role.attributes[:manageable_roles] }.flatten.uniq.reject { |role| role.match?("default") }
|
63
|
+
end
|
64
|
+
end
|
@@ -24,8 +24,14 @@ module Account::Onboarding::UserDetails::ControllerBase
|
|
24
24
|
# if you update your own user account, devise will normally kick you out, so we do this instead.
|
25
25
|
bypass_sign_in current_user.reload
|
26
26
|
|
27
|
+
# Only redirect users to the bulk invitation page if they're the
|
28
|
+
# one who created the team (meaning there's only one membership on the team).
|
27
29
|
if @user.details_provided?
|
28
|
-
|
30
|
+
if bulk_invitations_enabled? && @user.teams.first.memberships.size == 1
|
31
|
+
format.html { redirect_to new_account_onboarding_invitation_list_path(@user) }
|
32
|
+
else
|
33
|
+
format.html { redirect_to account_team_path(@user.teams.first), notice: "" }
|
34
|
+
end
|
29
35
|
else
|
30
36
|
format.html {
|
31
37
|
flash[:error] = I18n.t("global.notifications.all_fields_required")
|
@@ -24,7 +24,17 @@ module Account::Users::ControllerBase
|
|
24
24
|
def show
|
25
25
|
end
|
26
26
|
|
27
|
+
def updating_password_or_email?
|
28
|
+
params[:user].key?(:password) || params[:user].key?(:email)
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: We're keeping this method for backward compatibility in case someone in a downstream app
|
32
|
+
# might be using it. At some point in the future (unclear exactly when) we should remove it.
|
27
33
|
def updating_password?
|
34
|
+
ActiveSupport::Deprecation.warn(
|
35
|
+
"#updating_password? is deprecated. " \
|
36
|
+
"Use #updating_password_or_email? instead."
|
37
|
+
)
|
28
38
|
params[:user].key?(:password)
|
29
39
|
end
|
30
40
|
|
@@ -32,7 +42,7 @@ module Account::Users::ControllerBase
|
|
32
42
|
# PATCH/PUT /account/users/1.json
|
33
43
|
def update
|
34
44
|
respond_to do |format|
|
35
|
-
if
|
45
|
+
if updating_password_or_email? ? @user.update_with_password(user_params) : @user.update_without_password(user_params)
|
36
46
|
# if you update your own user account, devise will normally kick you out, so we do this instead.
|
37
47
|
bypass_sign_in current_user.reload
|
38
48
|
format.html { redirect_to [:edit, :account, @user], notice: t("users.notifications.updated") }
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Account::Onboarding::InvitationListsHelper
|
2
|
+
# When sending bulk invitations, the current user is the only one with a membership on the team.
|
3
|
+
# This means that we can access all of the available roles with the following code.
|
4
|
+
def available_roles
|
5
|
+
current_user.memberships.first.roles.map do |role|
|
6
|
+
[role.attributes[:key]] + role.attributes[:manageable_roles]
|
7
|
+
end.flatten.uniq.reject { |role| role.match?("default") }
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Account::Onboarding::InvitationLists::Base
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
belongs_to :team
|
6
|
+
has_many :invitations
|
7
|
+
has_many :memberships, through: :invitations
|
8
|
+
|
9
|
+
accepts_nested_attributes_for :invitations, :memberships
|
10
|
+
end
|
11
|
+
end
|
@@ -4,6 +4,7 @@ module Invitations::Base
|
|
4
4
|
included do
|
5
5
|
belongs_to :team
|
6
6
|
belongs_to :from_membership, class_name: "Membership"
|
7
|
+
belongs_to :invitation_list, class_name: "Account::Onboarding::InvitationList", optional: true
|
7
8
|
has_one :membership, dependent: :nullify
|
8
9
|
|
9
10
|
accepts_nested_attributes_for :membership
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= form.fields_for :invitations, Invitation.new do |invitation_form| %>
|
2
|
+
<div class="col-span-1">
|
3
|
+
<%= render 'shared/fields/email_field', form: invitation_form, method: :email, options: {autofocus: true} %>
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<%= invitation_form.fields_for :membership, Membership.new do |membership_form| %>
|
7
|
+
<div class="col-span-1">
|
8
|
+
<%= render 'shared/fields/super_select', form: membership_form, method: :role_ids, choices: available_roles, html_options: {multiple: true}, select2_options: {placeholder: t('.membership.roles.default')}, other_options: {label: t('.membership.roles.label')} %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<% @title = t('.header') %>
|
2
|
+
|
3
|
+
<%= render 'account/shared/workflow/box' do |box| %>
|
4
|
+
<% box.title @title %>
|
5
|
+
<% box.body do %>
|
6
|
+
<% within_fields_namespace(:self) do %>
|
7
|
+
<%= form_with(model: @account_onboarding_invitation_list, class: 'form', local: true) do |f| %>
|
8
|
+
<% f.object.errors.each do |error| %>
|
9
|
+
<%= render 'account/shared/forms/errors', form: f, attributes: [error.attribute], resource: @account_onboarding_invitation_list %>
|
10
|
+
<% end %>
|
11
|
+
<%= render 'account/shared/notices', form: f %>
|
12
|
+
|
13
|
+
<div class="grid gap-y gap-x grid-cols-2">
|
14
|
+
<% 1.times do %>
|
15
|
+
<%= render 'invitation_form', form: f %>
|
16
|
+
<% end %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="buttons">
|
20
|
+
<%= f.submit t('.buttons.next'), class: first_button_primary %>
|
21
|
+
<%= link_to t('.buttons.skip'), main_app.account_teams_path, class: first_button_primary %>
|
22
|
+
<% if other_teams.any? %>
|
23
|
+
<%= link_to t('global.buttons.back'), main_app.account_teams_path, class: first_button_primary %>
|
24
|
+
<% else %>
|
25
|
+
<%= link_to t('menus.main.labels.logout'), main_app.destroy_user_session_path(@user, onboard_logout: true), class: first_button_primary, method: 'delete' %>
|
26
|
+
<% end %>
|
27
|
+
</div>
|
28
|
+
<% end %>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
<% end %>
|
@@ -1,10 +1,6 @@
|
|
1
1
|
<%= form_for [:account, user], html: {id: dom_id(user, :details), class: 'form'} do |form| %>
|
2
2
|
<% with_field_settings form: form do %>
|
3
3
|
<div class="grid grid-cols-1 gap-y gap-x sm:grid-cols-2">
|
4
|
-
<div class="sm:col-span-2">
|
5
|
-
<%= render 'shared/fields/email_field', method: :email, options: {autofocus: true} %>
|
6
|
-
</div>
|
7
|
-
|
8
4
|
<div class="sm:col-span-1">
|
9
5
|
<%= render 'shared/fields/text_field', method: :first_name %>
|
10
6
|
</div>
|
@@ -23,18 +23,35 @@
|
|
23
23
|
<%= render 'account/users/oauth' %>
|
24
24
|
|
25
25
|
<%= render 'account/shared/box', divider: true do |box| %>
|
26
|
-
<% box.title t('.
|
26
|
+
<% box.title t('.email_and_password.header') %>
|
27
|
+
<% box.description t('.email_and_password.description') %>
|
27
28
|
<% box.body do %>
|
28
29
|
<% within_fields_namespace(:update_self) do %>
|
29
30
|
<%= form_for [:account, @user], html: {id: dom_id(@user, :password), class: 'form'} do |form| %>
|
30
31
|
<% with_field_settings form: form do %>
|
31
|
-
<%= render 'shared/fields/
|
32
|
-
|
33
|
-
|
32
|
+
<%= render 'shared/fields/email_field', method: :email, options: {autofocus: true} %>
|
33
|
+
|
34
|
+
<hr>
|
35
|
+
|
36
|
+
<p><%= t('.email_and_password.new_password') %></p>
|
37
|
+
|
38
|
+
<div class="grid grid-cols-1 gap-y gap-x sm:grid-cols-2">
|
39
|
+
<div class="sm:col-span-1">
|
40
|
+
<%= render 'shared/fields/password_field', method: :password, options: {show_strength_indicator: true}, other_options: { required: false } %>
|
41
|
+
</div>
|
42
|
+
<div class="sm:col-span-1">
|
43
|
+
<%= render 'shared/fields/password_field', method: :password_confirmation, other_options: { required: false, label: t('.email_and_password.confirm_new_password') } %>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<hr>
|
48
|
+
|
49
|
+
<p><%= t('.email_and_password.current_password') %></p>
|
50
|
+
<%= render 'shared/fields/password_field', method: :current_password, other_options: { required: true } %>
|
34
51
|
<% end %>
|
35
52
|
|
36
53
|
<div class="buttons">
|
37
|
-
<%= form.submit t('.buttons.
|
54
|
+
<%= form.submit t('.buttons.update_email_and_password'), class: "button" %>
|
38
55
|
</div>
|
39
56
|
<% end %>
|
40
57
|
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
en:
|
2
|
+
onboarding: &onboarding
|
3
|
+
invitation_lists:
|
4
|
+
buttons: &buttons
|
5
|
+
next: Next
|
6
|
+
skip: Skip
|
7
|
+
new:
|
8
|
+
header: Invite your team members
|
9
|
+
buttons: *buttons
|
10
|
+
invitation_form:
|
11
|
+
membership:
|
12
|
+
roles:
|
13
|
+
label: Roles
|
14
|
+
default: Default
|
15
|
+
account:
|
16
|
+
onboarding: *onboarding
|
@@ -5,20 +5,24 @@ en:
|
|
5
5
|
label: *label
|
6
6
|
buttons: &buttons
|
7
7
|
update_profile: Update Profile
|
8
|
-
|
8
|
+
update_email_and_password: Update Email & Password
|
9
9
|
edit:
|
10
10
|
section: "%{users_possessive} Profile"
|
11
11
|
profile:
|
12
12
|
header: Update Your Profile
|
13
|
-
description: You can update the
|
14
|
-
|
15
|
-
header: Update Your Password
|
13
|
+
description: You can update the way your name is displayed and your time zone.
|
14
|
+
email_and_password:
|
15
|
+
header: Update Your Email Address & Password
|
16
|
+
description: When you change these credentials we'll email you a confirmation.
|
17
|
+
new_password: If you don't want to change your password, leave these two fields blank.
|
18
|
+
current_password: For security reasons we need you to confirm your current password.
|
19
|
+
confirm_new_password: Confirm New Password
|
16
20
|
two_factor:
|
17
21
|
header: Two-Factor Authentication
|
18
22
|
description_enabled: 2FA is currently enabled for your account.
|
19
23
|
description_disabled: You can increase the security of your account by enabling two-factor authentication.
|
20
24
|
verification_fail: Verification failed. You can try enabling again. Please make sure you scan the new QR code with your Authenticator app.
|
21
|
-
verification_success: Success! Thanks for verifying. 2FA is now enabled.
|
25
|
+
verification_success: Success! Thanks for verifying. 2FA is now enabled.
|
22
26
|
warning: "In order to enable two-factor authentication, you <strong>must</strong> install an Authenticator app and <strong>enter your Verification Code from the app below</strong>. 2FA will not be enabled until you do so. This is to avoid you getting locked out of your account."
|
23
27
|
instructions: "Install <a href='https://authy.com/download/' target='_blank'>Authy</a> or <a href='https://support.google.com/accounts/answer/1066447'>Google Authentication</a> on your phone and scan the barcode displayed below."
|
24
28
|
recovery_codes: "You can also make a copy of the following recovery codes. Each one can help you get back into your account once should you lose access to the device you're using for two-factor authentication."
|
data/config/routes.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Note: before you attempt to manually wire up a `super_select` field, note that Super Scaffolding will automatically do that for your models. See [Super
|
1
|
+
Note: before you attempt to manually wire up a `super_select` field, note that Super Scaffolding will automatically do that for your models. See [Super Scaffolding](/docs/super-scaffolding.md) docs, section 4, for an example. And make sure Super Scaffolding doesn't automatically do what you're trying to do.
|
2
2
|
|
3
3
|
# Examples for the `super_select` Field Partial
|
4
4
|
|
data/docs/upgrades/yolo-130.md
CHANGED
@@ -136,7 +136,7 @@ gem "bullet_train-themes-tailwind_css", BULLET_TRAIN_VERSION
|
|
136
136
|
(We have to do this since we didn't start explicitly tracking versions until `1.4.0` and
|
137
137
|
want to make sure that our gem versions match what the starter repo expects.)
|
138
138
|
|
139
|
-
Then run `bundle
|
139
|
+
Then run `bundle install`
|
140
140
|
|
141
141
|
Then go ahead and commit the changes.
|
142
142
|
|
@@ -247,7 +247,7 @@ BULLET_TRAIN_VERSION = "1.3.1"
|
|
247
247
|
(We have to do this since we didn't start explicitly tracking versions until `1.4.0` and
|
248
248
|
want to make sure that our gem versions match what the starter repo expects.)
|
249
249
|
|
250
|
-
Then run `bundle
|
250
|
+
Then run `bundle install`
|
251
251
|
|
252
252
|
Then go ahead and commit the changes.
|
253
253
|
|
@@ -272,7 +272,7 @@ If anything fails, investigate the failures and get things working again, and co
|
|
272
272
|
git checkout main
|
273
273
|
git merge updating-bullet-train-v1.3.1
|
274
274
|
git push origin main
|
275
|
-
git branch -d updating-bullet-train-v1.3.1
|
275
|
+
git branch -d updating-bullet-train-v1.3.1
|
276
276
|
```
|
277
277
|
|
278
|
-
Alternatively, if you're using GitHub, you can push the `updating-bullet-train-v1.3.1` branch up and create a PR from it and let your CI integration do
|
278
|
+
Alternatively, if you're using GitHub, you can push the `updating-bullet-train-v1.3.1` branch up and create a PR from it and let your CI integration do its thing and then merge in the PR and delete the branch there. (That's what we typically do.)
|
data/docs/upgrades/yolo-140.md
CHANGED
@@ -57,7 +57,7 @@ generate a new one that matches what you need:
|
|
57
57
|
|
58
58
|
```
|
59
59
|
git checkout HEAD -- Gemfile.lock
|
60
|
-
bundle
|
60
|
+
bundle install
|
61
61
|
```
|
62
62
|
|
63
63
|
If you choose to sort out `Gemfile.lock` by hand it's a good idea to run `bundle install` just to make
|
@@ -84,11 +84,11 @@ If anything fails, investigate the failures and get things working again, and co
|
|
84
84
|
|
85
85
|
```
|
86
86
|
git checkout main
|
87
|
-
git merge updating-bullet-train-v1.
|
87
|
+
git merge updating-bullet-train-v1.4.0
|
88
88
|
git push origin main
|
89
|
-
git branch -d updating-bullet-train-v1.
|
89
|
+
git branch -d updating-bullet-train-v1.4.0
|
90
90
|
```
|
91
91
|
|
92
|
-
Alternatively, if you're using GitHub, you can push the `updating-bullet-train-v1.
|
92
|
+
Alternatively, if you're using GitHub, you can push the `updating-bullet-train-v1.4.0` branch up and create a PR from it and let your CI integration do it's thing and then merge in the PR and delete the branch there. (That's what we typically do.)
|
93
93
|
|
94
94
|
|
data/docs/upgrades.md
CHANGED
@@ -30,6 +30,8 @@ recent version of the starter repository should cause a merge conflict in Git. T
|
|
30
30
|
opportunity to compare our upstream changes with your local customizations and allow you to resolve them in a way that makes sense for
|
31
31
|
your application.
|
32
32
|
|
33
|
+
⚠️ If you have ejected files or a new custom theme, there is a possibility that those ejected files need to be updated although no merge conflicts arose from `git merge`. You will need to compare your ejected views with the original views in [bullet_train-core](https://github.com/bullet-train-co/bullet_train-core) to ensure everything is working properly. Please refer to the documentation on [indirection](indirection) to find out more about ejected views.
|
34
|
+
|
33
35
|
### 1. Decide which version you want to upgrade to
|
34
36
|
|
35
37
|
For the purposes of these instructions we'll assume that you're on version `1.4.0` and are going to upgrade to version `1.4.1`.
|
@@ -66,7 +68,7 @@ git checkout -b updating-bullet-train-1.4.1
|
|
66
68
|
|
67
69
|
### 5. Merge in the newest stuff from Bullet Train and resolve any merge conflicts.
|
68
70
|
|
69
|
-
Each version of the starter repo is tagged, so you can merge in the tag from the
|
71
|
+
Each version of the starter repo is tagged, so you can merge in the tag from the upstream repo.
|
70
72
|
|
71
73
|
```
|
72
74
|
git merge v1.4.1
|
@@ -114,5 +116,5 @@ git branch -d updating-bullet-train-1.4.1
|
|
114
116
|
```
|
115
117
|
|
116
118
|
Alternatively, if you're using GitHub, you can push the `updating-bullet-train-1.4.1` branch up and create a
|
117
|
-
PR from it and let your CI integration do
|
119
|
+
PR from it and let your CI integration do its thing and then merge in the PR and delete the branch there.
|
118
120
|
(That's what we typically do.)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module BulletTrain
|
2
2
|
class Configuration
|
3
3
|
include Singleton
|
4
|
-
attr_accessor :strong_passwords, :incoming_webhooks_parent_class_name
|
4
|
+
attr_accessor :strong_passwords, :enable_bulk_invitations, :incoming_webhooks_parent_class_name
|
5
5
|
|
6
6
|
@@config = nil
|
7
7
|
|
@@ -10,6 +10,7 @@ module BulletTrain
|
|
10
10
|
|
11
11
|
# Default values
|
12
12
|
@strong_passwords = true
|
13
|
+
@enable_bulk_invitations = false
|
13
14
|
@incoming_webhooks_parent_class_name = "ApplicationRecord"
|
14
15
|
end
|
15
16
|
|
@@ -18,6 +19,10 @@ module BulletTrain
|
|
18
19
|
@@config&.strong_passwords
|
19
20
|
end
|
20
21
|
|
22
|
+
def enable_bulk_invitations
|
23
|
+
@@config&.enable_bulk_invitations
|
24
|
+
end
|
25
|
+
|
21
26
|
def incoming_webhooks_parent_class_name
|
22
27
|
@@config&.incoming_webhooks_parent_class_name
|
23
28
|
end
|
@@ -11,12 +11,16 @@ module BulletTrain
|
|
11
11
|
def run(eject: false, open: false, force: false, interactive: false)
|
12
12
|
# Try to figure out what kind of thing they're trying to look up.
|
13
13
|
source_file = calculate_source_file_details
|
14
|
+
source_file[:relative_path] = nil
|
14
15
|
|
15
16
|
if source_file[:absolute_path]
|
16
17
|
puts ""
|
17
18
|
puts "Absolute path:".green
|
18
19
|
puts " #{source_file[:absolute_path]}".green
|
19
20
|
puts ""
|
21
|
+
|
22
|
+
source_file[:relative_path] = source_file[:absolute_path].split(/(?=#{source_file[:package_name]})/).pop
|
23
|
+
|
20
24
|
if source_file[:package_name].present?
|
21
25
|
puts "Package name:".green
|
22
26
|
puts " #{source_file[:package_name]}".green
|
@@ -44,9 +48,9 @@ module BulletTrain
|
|
44
48
|
File.open((source_file[:project_path]).to_s, "w+") do |file|
|
45
49
|
case source_file[:project_path].split(".").last
|
46
50
|
when "rb", "yml"
|
47
|
-
file.puts "# Ejected from `#{source_file[:package_name]}`.\n\n"
|
51
|
+
file.puts "# Ejected from `#{source_file[:relative_path] || source_file[:package_name]}`.\n\n"
|
48
52
|
when "erb"
|
49
|
-
file.puts "<% # Ejected from `#{source_file[:package_name]}`. %>\n\n"
|
53
|
+
file.puts "<% # Ejected from `#{source_file[:relative_path] || source_file[:package_name]}`. %>\n\n"
|
50
54
|
end
|
51
55
|
end
|
52
56
|
`cat #{source_file[:absolute_path]} >> #{source_file[:project_path]}`.strip
|
data/lib/bullet_train/version.rb
CHANGED
data/lib/bullet_train.rb
CHANGED
@@ -167,6 +167,10 @@ def openai_organization_exists?
|
|
167
167
|
ENV["OPENAI_ORGANIZATION_ID"]
|
168
168
|
end
|
169
169
|
|
170
|
+
def bulk_invitations_enabled?
|
171
|
+
BulletTrain::Configuration.enable_bulk_invitations
|
172
|
+
end
|
173
|
+
|
170
174
|
def disable_developer_menu?
|
171
175
|
ENV["DISABLE_DEVELOPER_MENU"].present?
|
172
176
|
end
|
@@ -82,20 +82,30 @@ namespace :bullet_train do
|
|
82
82
|
gem_names.each do |gem|
|
83
83
|
puts "Searching for locales in #{gem}...".blue
|
84
84
|
gem_path = `bundle show #{gem}`.chomp
|
85
|
+
gem_with_version = gem_path.split("/").last
|
85
86
|
locales = Dir.glob("#{gem_path}/**/config/locales/**/*.yml").reject { |path| path.match?("dummy") }
|
86
87
|
next if locales.empty?
|
87
88
|
|
88
89
|
puts "Found locales. Ejecting to your application...".green
|
89
90
|
locales.each do |locale|
|
90
|
-
relative_path = locale.split(
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
91
|
+
relative_path = locale.split(/(?=#{gem_with_version}\/config\/locales)/).last
|
92
|
+
path_in_locale = locale.split("/config/locales").pop
|
93
|
+
|
94
|
+
base_path = relative_path.split("/")
|
95
|
+
base_path.pop
|
96
|
+
base_path = base_path.join("/")
|
97
|
+
starter_repo_locale_path = base_path.gsub(gem_with_version, ".")
|
98
|
+
|
99
|
+
FileUtils.mkdir_p(starter_repo_locale_path) unless Dir.exist?(starter_repo_locale_path)
|
100
|
+
|
101
|
+
unless File.exist?("config/locales#{path_in_locale}")
|
102
|
+
puts "Ejecting #{path_in_locale}..."
|
103
|
+
File.new("config/locales#{path_in_locale}", "w")
|
104
|
+
`cp #{locale} config/locales#{path_in_locale}`
|
105
|
+
file = Pathname.new("config/locales#{path_in_locale}")
|
106
|
+
lines = file.readlines
|
107
|
+
lines.unshift("# Ejected from #{relative_path}\n\n")
|
108
|
+
file.write(lines.join)
|
99
109
|
end
|
100
110
|
end
|
101
111
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet_train
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: standard
|
@@ -513,6 +513,7 @@ files:
|
|
513
513
|
- app/assets/config/bullet_train_manifest.js
|
514
514
|
- app/controllers/account/invitations_controller.rb
|
515
515
|
- app/controllers/account/memberships_controller.rb
|
516
|
+
- app/controllers/account/onboarding/invitation_lists_controller.rb
|
516
517
|
- app/controllers/account/onboarding/user_details_controller.rb
|
517
518
|
- app/controllers/account/onboarding/user_email_controller.rb
|
518
519
|
- app/controllers/account/teams_controller.rb
|
@@ -521,6 +522,7 @@ files:
|
|
521
522
|
- app/controllers/concerns/account/controllers/base.rb
|
522
523
|
- app/controllers/concerns/account/invitations/controller_base.rb
|
523
524
|
- app/controllers/concerns/account/memberships/controller_base.rb
|
525
|
+
- app/controllers/concerns/account/onboarding/invitation_lists/controller_base.rb
|
524
526
|
- app/controllers/concerns/account/onboarding/user_details/controller_base.rb
|
525
527
|
- app/controllers/concerns/account/onboarding/user_email/controller_base.rb
|
526
528
|
- app/controllers/concerns/account/teams/controller_base.rb
|
@@ -541,6 +543,7 @@ files:
|
|
541
543
|
- app/helpers/account/locale_helper.rb
|
542
544
|
- app/helpers/account/markdown_helper.rb
|
543
545
|
- app/helpers/account/memberships_helper.rb
|
546
|
+
- app/helpers/account/onboarding/invitation_lists_helper.rb
|
544
547
|
- app/helpers/account/role_helper.rb
|
545
548
|
- app/helpers/account/teams_helper.rb
|
546
549
|
- app/helpers/account/users_helper.rb
|
@@ -567,12 +570,14 @@ files:
|
|
567
570
|
- app/mailers/concerns/mailers/base.rb
|
568
571
|
- app/mailers/devise_mailer.rb
|
569
572
|
- app/mailers/user_mailer.rb
|
573
|
+
- app/models/account/onboarding/invitation_list.rb
|
570
574
|
- app/models/address.rb
|
571
575
|
- app/models/addresses/continent.rb
|
572
576
|
- app/models/addresses/country.rb
|
573
577
|
- app/models/addresses/region.rb
|
574
578
|
- app/models/addresses/subcontinent.rb
|
575
579
|
- app/models/billing/mock_limiter.rb
|
580
|
+
- app/models/concerns/account/onboarding/invitation_lists/base.rb
|
576
581
|
- app/models/concerns/addresses/base.rb
|
577
582
|
- app/models/concerns/addresses/continents/base.rb
|
578
583
|
- app/models/concerns/addresses/countries/base.rb
|
@@ -606,6 +611,8 @@ files:
|
|
606
611
|
- app/views/account/memberships/edit.html.erb
|
607
612
|
- app/views/account/memberships/index.html.erb
|
608
613
|
- app/views/account/memberships/show.html.erb
|
614
|
+
- app/views/account/onboarding/invitation_lists/_invitation_form.html.erb
|
615
|
+
- app/views/account/onboarding/invitation_lists/new.html.erb
|
609
616
|
- app/views/account/onboarding/user_details/edit.html.erb
|
610
617
|
- app/views/account/onboarding/user_email/edit.html.erb
|
611
618
|
- app/views/account/teams/_breadcrumbs.html.erb
|
@@ -664,6 +671,7 @@ files:
|
|
664
671
|
- config/locales/en/invitations.en.yml
|
665
672
|
- config/locales/en/memberships.en.yml
|
666
673
|
- config/locales/en/oauth.en.yml
|
674
|
+
- config/locales/en/onboarding/invitation_lists.en.yml
|
667
675
|
- config/locales/en/onboarding/user_details.en.yml
|
668
676
|
- config/locales/en/onboarding/user_email.en.yml
|
669
677
|
- config/locales/en/roles.en.yml
|