bullet_train 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/bullet_train_manifest.js +0 -0
- data/app/controllers/account/invitations_controller.rb +146 -0
- data/app/controllers/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments_controller.rb +83 -0
- data/app/controllers/account/memberships_controller.rb +132 -0
- data/app/controllers/account/onboarding/user_details_controller.rb +63 -0
- data/app/controllers/account/onboarding/user_email_controller.rb +65 -0
- data/app/controllers/account/teams_controller.rb +122 -0
- data/app/controllers/account/users_controller.rb +59 -0
- data/app/helpers/account/invitations_helper.rb +2 -0
- data/app/helpers/account/memberships_helper.rb +9 -0
- data/app/helpers/account/teams_helper.rb +80 -0
- data/app/helpers/account/users_helper.rb +81 -0
- data/app/helpers/invitation_only_helper.rb +10 -0
- data/app/helpers/invitations_helper.rb +17 -0
- data/app/models/invitation.rb +73 -0
- data/app/models/membership.rb +164 -0
- data/app/models/memberships/reassignments/assignment.rb +12 -0
- data/app/models/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignment.rb +38 -0
- data/app/models/memberships/reassignments.rb +5 -0
- data/app/models/team.rb +81 -0
- data/app/models/user.rb +191 -0
- data/app/views/account/invitations/_breadcrumbs.html.erb +9 -0
- data/app/views/account/invitations/_form.html.erb +49 -0
- data/app/views/account/invitations/_invitation.json.jbuilder +7 -0
- data/app/views/account/invitations/index.json.jbuilder +1 -0
- data/app/views/account/invitations/new.html.erb +12 -0
- data/app/views/account/invitations/show.html.erb +30 -0
- data/app/views/account/invitations/show.json.jbuilder +1 -0
- data/app/views/account/memberships/_breadcrumbs.html.erb +8 -0
- data/app/views/account/memberships/_form.html.erb +45 -0
- data/app/views/account/memberships/_index.html.erb +66 -0
- data/app/views/account/memberships/_menu_item.html.erb +8 -0
- data/app/views/account/memberships/_tombstones.html.erb +59 -0
- data/app/views/account/memberships/edit.html.erb +22 -0
- data/app/views/account/memberships/index.html.erb +7 -0
- data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/_breadcrumbs.html.erb +10 -0
- data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/_form.html.erb +24 -0
- data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/_scaffolding_completely_concrete_tangible_things_reassignment.json.jbuilder +8 -0
- data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/index.json.jbuilder +1 -0
- data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/new.html.erb +11 -0
- data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/show.json.jbuilder +1 -0
- data/app/views/account/memberships/show.html.erb +60 -0
- data/app/views/account/onboarding/user_details/edit.html.erb +72 -0
- data/app/views/account/onboarding/user_email/edit.html.erb +33 -0
- data/app/views/account/teams/_breadcrumbs.html.erb +11 -0
- data/app/views/account/teams/_form.html.erb +22 -0
- data/app/views/account/teams/_index.html.erb +33 -0
- data/app/views/account/teams/_menu_item.html.erb +8 -0
- data/app/views/account/teams/_team.json.jbuilder +9 -0
- data/app/views/account/teams/edit.html.erb +12 -0
- data/app/views/account/teams/index.html.erb +6 -0
- data/app/views/account/teams/index.json.jbuilder +1 -0
- data/app/views/account/teams/new.html.erb +88 -0
- data/app/views/account/teams/show.html.erb +25 -0
- data/app/views/account/teams/show.json.jbuilder +1 -0
- data/app/views/account/users/_breadcrumbs.html.erb +4 -0
- data/app/views/account/users/_form.html.erb +39 -0
- data/app/views/account/users/edit.html.erb +50 -0
- data/app/views/account/users/show.html.erb +17 -0
- data/config/locales/en/invitations.en.yml +69 -0
- data/config/locales/en/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments.en.yml +42 -0
- data/config/locales/en/memberships.en.yml +99 -0
- data/config/locales/en/onboarding/user_details.en.yml +11 -0
- data/config/locales/en/onboarding/user_email.en.yml +13 -0
- data/config/locales/en/teams.en.yml +85 -0
- data/config/locales/en/users.en.yml +110 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20161115160419_devise_create_users.rb +41 -0
- data/db/migrate/20161116003852_add_api_key_to_user.rb +6 -0
- data/db/migrate/20161117154605_create_teams.rb +10 -0
- data/db/migrate/20161117154709_create_memberships.rb +11 -0
- data/db/migrate/20161203193930_add_current_team_to_user.rb +5 -0
- data/db/migrate/20161204234150_create_invitations.rb +11 -0
- data/db/migrate/20161205154821_add_team_to_invitation.rb +5 -0
- data/db/migrate/20161205164613_add_admin_to_invitation.rb +5 -0
- data/db/migrate/20170908205756_add_names_to_user.rb +6 -0
- data/db/migrate/20170915215309_add_team_to_thing.rb +5 -0
- data/db/migrate/20171105001408_remove_api_key_from_user.rb +6 -0
- data/db/migrate/20180326124105_add_timezone_to_user.rb +5 -0
- data/db/migrate/20180902142350_create_membership_roles.rb +10 -0
- data/db/migrate/20180902143758_remove_admin_from_membership.rb +5 -0
- data/db/migrate/20180902154611_create_invitation_roles.rb +10 -0
- data/db/migrate/20180902154652_migrate_admin_flag_on_invitations.rb +14 -0
- data/db/migrate/20180902195848_remove_admin_from_invitation.rb +5 -0
- data/db/migrate/20180903101707_add_last_seen_at_to_users.rb +5 -0
- data/db/migrate/20190321203224_add_profile_photo_id_to_user.rb +5 -0
- data/db/migrate/20190519230202_add_ability_cache_to_user.rb +5 -0
- data/db/migrate/20190628194704_add_last_notification_email_sent_at_to_user.rb +5 -0
- data/db/migrate/20200211034208_add_invitation_to_membership.rb +5 -0
- data/db/migrate/20200211044616_drop_invitation_roles_table.rb +10 -0
- data/db/migrate/20200213052748_add_former_user_fields_to_membership.rb +8 -0
- data/db/migrate/20200213235037_add_former_user_to_user.rb +7 -0
- data/db/migrate/20200219013834_add_added_by_to_membership.rb +5 -0
- data/db/migrate/20200219015116_rename_from_user_to_from_membership.rb +5 -0
- data/db/migrate/20200726222314_add_being_destroyed_to_team.rb +5 -0
- data/db/migrate/20200727171308_add_devise_two_factor_to_users.rb +9 -0
- data/db/migrate/20200727175949_add_devise_two_factor_backupable_to_users.rb +5 -0
- data/db/migrate/20210304133200_add_time_zone_to_team.rb +5 -0
- data/db/migrate/20210816072419_add_locale_to_users.rb +5 -0
- data/db/migrate/20210816072508_add_locale_to_teams.rb +5 -0
- data/db/migrate/20211020200855_add_doorkeeper_application_to_memberships.rb +5 -0
- data/db/migrate/20211027002944_add_doorkeeper_application_to_users.rb +5 -0
- data/lib/bullet_train/engine.rb +4 -0
- data/lib/bullet_train/version.rb +3 -0
- data/lib/bullet_train.rb +6 -0
- data/lib/tasks/bullet_train_tasks.rake +4 -0
- metadata +168 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
<%= render 'account/shared/page' do |p| %>
|
2
|
+
<% p.content_for :title, t('.section') %>
|
3
|
+
<% p.content_for :body do %>
|
4
|
+
<%= render 'account/shared/box', divider: true do |p| %>
|
5
|
+
<% p.content_for :title do %>
|
6
|
+
<% if @membership.unclaimed? %>
|
7
|
+
<%= t('.invitation_header') %>
|
8
|
+
<% elsif @membership.tombstone? %>
|
9
|
+
<%= t('.tombstone_header') %>
|
10
|
+
<% else %>
|
11
|
+
<%= t('.header') %>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% p.content_for :description do %>
|
16
|
+
<%= t('.description') %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% p.content_for :body do %>
|
20
|
+
<% with_attribute_settings object: @membership, strategy: :label do %>
|
21
|
+
<%= render 'shared/attributes/text', attribute: :name %>
|
22
|
+
<%= render 'shared/attributes/base' do |p| %>
|
23
|
+
<% p.content_for :heading, t('.fields.role_ids.heading') %>
|
24
|
+
<% p.content_for :body do %>
|
25
|
+
<% if @membership.assignable_roles.any? %>
|
26
|
+
<%= @membership.assignable_roles.map { |role| t(".fields.role_ids.options.#{role.key}.label") }.to_sentence %>
|
27
|
+
<% else %>
|
28
|
+
<%= t(".fields.role_ids.none") %>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
<%# 🚅 super scaffolding will insert new fields above this line. %>
|
34
|
+
<% end %>
|
35
|
+
|
36
|
+
<% p.content_for :actions do %>
|
37
|
+
<% if @membership.tombstone? %>
|
38
|
+
<%= link_to t('.buttons.reinvite'), [:reinvite, :account, @membership], class: first_button_primary, method: :post, data: {confirm: t('.buttons.confirmations.reinvite', membership_name: @membership.name)} if can? :edit, @membership %>
|
39
|
+
<% end %>
|
40
|
+
|
41
|
+
<%= link_to t('.buttons.edit'), [:edit, :account, @membership], class: first_button_primary if can? :edit, @membership %>
|
42
|
+
|
43
|
+
<% unless @membership.tombstone? %>
|
44
|
+
<% if @membership.admin? %>
|
45
|
+
<%= link_to t('.buttons.demote'), [:demote, :account, @membership], method: :post, data: { confirm: t('global.confirm_message') }, class: first_button_primary if can? :demote, @membership %>
|
46
|
+
<% else %>
|
47
|
+
<%= link_to t('.buttons.promote'), [:promote, :account, @membership], method: :post, data: { confirm: t('global.confirm_message') }, class: first_button_primary if can? :promote, @membership %>
|
48
|
+
<% end %>
|
49
|
+
<%= button_to t(".buttons.#{membership_destroy_locale_key(@membership)}"), [:account, @membership], method: :delete, data: { confirm: t(".buttons.confirmations.#{membership_destroy_locale_key(@membership)}", model_locales(@membership)) }, class: first_button_primary if can? :destroy, @membership %>
|
50
|
+
<% end %>
|
51
|
+
|
52
|
+
<%= link_to t('global.buttons.back'), [:account, @team, :memberships], class: first_button_primary %>
|
53
|
+
<% end %>
|
54
|
+
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
<%= render 'account/scaffolding/completely_concrete/tangible_things/index', tangible_things: @membership.scaffolding_completely_concrete_tangible_things, context: @membership if @membership.scaffolding_completely_concrete_tangible_things.any? %>
|
58
|
+
<%# 🚅 super scaffolding will insert new children above this line. %>
|
59
|
+
<% end %>
|
60
|
+
<% end %>
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<% @title = t('.header') %>
|
2
|
+
|
3
|
+
<%= render 'account/shared/workflow/box' do |p| %>
|
4
|
+
<% p.content_for :title, @title %>
|
5
|
+
<% p.content_for :body do %>
|
6
|
+
<% within_fields_namespace(:self) do %>
|
7
|
+
<%= form_for @user, url: account_onboarding_user_detail_path(@user), method: :put, html: {class: 'form'} do |f| %>
|
8
|
+
<%= render 'account/shared/forms/errors', form: f %>
|
9
|
+
|
10
|
+
<div class="grid grid-cols-1 gap-y gap-x sm:grid-cols-2">
|
11
|
+
<div class="sm:col-span-1">
|
12
|
+
<%= render 'shared/fields/text_field', form: f, method: :first_name, options: {autofocus: true} %>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div class="sm:col-span-1">
|
16
|
+
<%= render 'shared/fields/text_field', form: f, method: :last_name %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="sm:col-span-2">
|
20
|
+
<% # only edit the team name if this user is an admin and they are the first user. %>
|
21
|
+
<% # yes, that's redundant. %>
|
22
|
+
<% if can?(:edit, f.object.current_team) && f.object.current_team.users.count == 1 %>
|
23
|
+
<%= f.fields_for :current_team do |tf| %>
|
24
|
+
<%= render 'shared/fields/text_field', form: tf, method: :name %>
|
25
|
+
<% end %>
|
26
|
+
<% end %>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div class="sm:col-span-2">
|
30
|
+
<%= render 'shared/fields/super_select', form: f, method: :time_zone,
|
31
|
+
choices: time_zone_options_for_select(@user.time_zone, nil, ActiveSupport::TimeZone),
|
32
|
+
other_options: {search: true} %>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div class="buttons">
|
37
|
+
<%= f.submit t('.buttons.next'), class: first_button_primary %>
|
38
|
+
<% if other_teams.any? %>
|
39
|
+
<%= link_to t('global.buttons.back'), main_app.account_teams_path, class: first_button_primary %>
|
40
|
+
<% else %>
|
41
|
+
<%= link_to t('menus.main.labels.logout'), main_app.destroy_user_session_path, class: first_button_primary, method: 'delete' %>
|
42
|
+
<% end %>
|
43
|
+
</div>
|
44
|
+
<% end %>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
<script type="text/javascript">
|
50
|
+
$(document).on('turbo:load', function() {
|
51
|
+
|
52
|
+
// generate a mapping of js timezones compared to rails timezones.
|
53
|
+
var jsTimezoneMapping = {
|
54
|
+
<% ActiveSupport::TimeZone::MAPPING.each do |key, value| %>
|
55
|
+
"<%= value.html_safe %>": "<%= key.html_safe %>",
|
56
|
+
<% end %>
|
57
|
+
}
|
58
|
+
|
59
|
+
// figure out the rails timezone value.
|
60
|
+
var railsValue = jsTimezoneMapping[jstz.determine().name()];
|
61
|
+
|
62
|
+
// set the form accordingly.
|
63
|
+
var $option = $("#user_time_zone option[value=\"" + railsValue + "\"]")
|
64
|
+
$option.prop('selected', true);
|
65
|
+
|
66
|
+
// update the select2 as well. is there a better way to handle this?
|
67
|
+
// why don't _they_ handle this for us?
|
68
|
+
$("#select2-user_time_zone-container").attr('title', $option.text());
|
69
|
+
$("#select2-user_time_zone-container").text($option.text());
|
70
|
+
|
71
|
+
});
|
72
|
+
</script>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<% @title = t('.header') %>
|
2
|
+
|
3
|
+
<%= render 'account/shared/workflow/box' do |p| %>
|
4
|
+
<% p.content_for :title, @title %>
|
5
|
+
<% p.content_for :body do %>
|
6
|
+
<% within_fields_namespace(:self) do %>
|
7
|
+
<%= form_for @user, url: account_onboarding_user_email_path(@user), method: :put, html: {class: 'form'} do |f| %>
|
8
|
+
<% if @email_taken %>
|
9
|
+
<%= render 'account/shared/alert', color: 'red' do %>
|
10
|
+
<%= t('.email_taken') %>
|
11
|
+
<% end %>
|
12
|
+
<% else %>
|
13
|
+
<%= render 'account/shared/alert' do %>
|
14
|
+
<%= t('.description') %>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<%= render 'account/shared/forms/errors', form: f %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<%= render 'shared/fields/email_field', form: f, method: :email, options: {autofocus: true} %>
|
21
|
+
|
22
|
+
<div class="buttons">
|
23
|
+
<%= f.submit t('.buttons.next'), class: first_button_primary %>
|
24
|
+
<% if current_user.teams.any? %>
|
25
|
+
<%= link_to t('global.buttons.back'), main_app.account_teams_path, class: first_button_primary %>
|
26
|
+
<% else %>
|
27
|
+
<%= link_to t('menus.main.labels.logout'), main_app.destroy_user_session_path, class: first_button_primary, method: 'delete' %>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
30
|
+
<% end %>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% team ||= @team %>
|
2
|
+
<% unless current_user.one_team? %>
|
3
|
+
<%= render 'account/shared/breadcrumb', label: t('.label'), url: [:account, :teams], first: true %>
|
4
|
+
<% if team&.persisted? %>
|
5
|
+
<%= render 'account/shared/breadcrumb', label: team.name, url: [:account, team] %>
|
6
|
+
<% end %>
|
7
|
+
<% end %>
|
8
|
+
<%= render 'account/shared/breadcrumbs/actions', only_for: 'teams' %>
|
9
|
+
<% if (action_name == 'show' && controller_name == 'teams') || current_user.one_team? %>
|
10
|
+
<%= render 'account/shared/breadcrumb', label: 'Dashboard', url: [:account, team] %>
|
11
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<%= form_with model: [:account, team], local: true, class: 'form' do |form| %>
|
2
|
+
<%= render 'account/shared/forms/errors', form: form %>
|
3
|
+
|
4
|
+
<% with_field_settings form: form do %>
|
5
|
+
<%= render 'shared/fields/text_field', method: :name, options: {autofocus: true} %>
|
6
|
+
|
7
|
+
<%= render 'shared/fields/super_select', method: :time_zone,
|
8
|
+
choices: time_zone_options_for_select(team.time_zone, nil, ActiveSupport::TimeZone),
|
9
|
+
other_options: {search: true} %>
|
10
|
+
|
11
|
+
<% if multiple_locales? %>
|
12
|
+
<%= render 'shared/fields/buttons', method: :locale, options: t("locale.locales") %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<%# 🚅 super scaffolding will insert new fields above this line. %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<div class="buttons">
|
19
|
+
<%= form.submit (form.object.persisted? ? t('.buttons.update') : t('.buttons.create')), class: "button" %>
|
20
|
+
<%= link_to t('global.buttons.cancel'), form.object.persisted? ? [:account, team] : [:account, :teams], class: "button-secondary" %>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<ul class="space-y">
|
2
|
+
<% @teams.each do |team| %>
|
3
|
+
<li class="bg-white shadow overflow-hidden sm:rounded-md dark:bg-sealBlue-400">
|
4
|
+
<%= link_to [:account, team], class: "group block hover:bg-gray-50 dark:hover:bg-sealBlue-400 dark:text-sealBlue-800" do %>
|
5
|
+
<div class="px-4 py-4 flex items-center sm:pl-8 sm:pr-6">
|
6
|
+
<div class="min-w-0 flex-1 sm:flex sm:items-center sm:justify-between">
|
7
|
+
<div>
|
8
|
+
<div class="flex text-xl font-semibold text-blue uppercase group-hover:text-blue-dark tracking-widest dark:text-white">
|
9
|
+
<%= team.name %>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
<div class="mt-4 flex-shrink-0 sm:mt-0">
|
13
|
+
<div class="flex overflow-hidden">
|
14
|
+
<%= render 'account/shared/memberships/photos', memberships: team.memberships.current_and_invited.first(10) %>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
<div class="ml-5 flex-shrink-0">
|
19
|
+
<svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
20
|
+
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
21
|
+
</svg>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
25
|
+
</li>
|
26
|
+
<% end %>
|
27
|
+
</ul>
|
28
|
+
|
29
|
+
<% if show_sign_up_options? && can?(:create, Team.new) %>
|
30
|
+
<div class="pt-5">
|
31
|
+
<%= link_to t('.buttons.create'), new_account_team_path(@team), class: 'button' %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= render 'account/shared/page' do |p| %>
|
2
|
+
<% p.content_for :title, t('.section') %>
|
3
|
+
<% p.content_for :body do %>
|
4
|
+
<%= render 'account/shared/box', divider: true do |p| %>
|
5
|
+
<% p.content_for :title, t('.header') %>
|
6
|
+
<% p.content_for :description, t('.description') %>
|
7
|
+
<% p.content_for :body do %>
|
8
|
+
<%= render 'form', team: @team %>
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
json.array! @teams, partial: "teams/team", as: :team
|
@@ -0,0 +1,88 @@
|
|
1
|
+
<%
|
2
|
+
@title = if current_user.former_user? && current_user.teams.none?
|
3
|
+
t('teams.new.former_user_header')
|
4
|
+
else
|
5
|
+
t('teams.new.header')
|
6
|
+
end
|
7
|
+
%>
|
8
|
+
|
9
|
+
<%= render 'account/shared/workflow/box' do |p| %>
|
10
|
+
<% p.content_for :title, @title %>
|
11
|
+
<% p.content_for :body do %>
|
12
|
+
<%= form_with model: @team, url: [:account, @team], local: true, class: 'form' do |form| %>
|
13
|
+
<%= render 'account/shared/notices' %>
|
14
|
+
<%= render 'account/shared/forms/errors', form: form %>
|
15
|
+
|
16
|
+
<% if current_user.former_user? && current_user.teams.none? %>
|
17
|
+
|
18
|
+
<%= render 'account/shared/alert' do %>
|
19
|
+
<%= raw t('.alert', user_email: current_user.email) %>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<p><%= t('.you_can') %></p>
|
23
|
+
|
24
|
+
<div class="space-y-3">
|
25
|
+
<h3 class="text-lg leading-5 font-semibold"><%= t('.invitation_header') %></h3>
|
26
|
+
<p><%= t('.invitation') %></p>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<%= render 'account/shared/decision_line' %>
|
30
|
+
|
31
|
+
<div class="space-y-3">
|
32
|
+
<h3 class="text-lg leading-5 font-semibold"><%= t('.logout_header') %></h3>
|
33
|
+
<p><%= t('.log_out') %></p>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<%= link_to t('menus.main.labels.logout'), main_app.destroy_user_session_path, class: 'button-alternative full', method: 'delete' %></p>
|
37
|
+
|
38
|
+
<%= render 'account/shared/decision_line' %>
|
39
|
+
|
40
|
+
<% # this is weird, but it's closed below where commented. %>
|
41
|
+
<div class="space-y-3">
|
42
|
+
<h3 class="text-lg leading-5 font-semibold"><%= t('.new_team_header') %></h3>
|
43
|
+
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
<% if invited? || !invitation_only? %>
|
47
|
+
|
48
|
+
<%= render 'shared/fields/text_field', form: form, method: :name, options: {autofocus: true} %>
|
49
|
+
<%= render 'shared/fields/super_select', form: form, method: :time_zone, choices: time_zone_options_for_select(current_user.time_zone, nil, ActiveSupport::TimeZone) %>
|
50
|
+
<%# 🚅 super scaffolding will insert new fields above this line. %>
|
51
|
+
|
52
|
+
<div class="buttons">
|
53
|
+
<% other_teams = current_user.teams.select(&:persisted?).count > 0 %>
|
54
|
+
<%= form.submit t('.buttons.create'), class: "button #{'full' unless other_teams}" %>
|
55
|
+
<% if other_teams %>
|
56
|
+
<%= link_to t('global.buttons.back'), account_teams_path, class: 'button-secondary' %>
|
57
|
+
<% end %>
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<% else %>
|
61
|
+
|
62
|
+
<% if current_user.former_user? && current_user.teams.none? %>
|
63
|
+
<p><%= t('teams.notifications.invitation_only') %></p>
|
64
|
+
<% else %>
|
65
|
+
<%= render 'account/shared/alert' do %>
|
66
|
+
<%= t('teams.notifications.invitation_only') %>
|
67
|
+
<% end %>
|
68
|
+
|
69
|
+
<div class="buttons">
|
70
|
+
<% if current_user.teams.any? %>
|
71
|
+
<%= link_to t('global.buttons.back'), main_app.account_teams_path, class: first_button_primary %>
|
72
|
+
<% else %>
|
73
|
+
<%= link_to t('menus.main.labels.logout'), main_app.destroy_user_session_path, class: first_button_primary, method: 'delete' %>
|
74
|
+
<% end %>
|
75
|
+
</div>
|
76
|
+
<% end %>
|
77
|
+
|
78
|
+
<% end %>
|
79
|
+
|
80
|
+
<% # this is weird, but it's opened above where commented. %>
|
81
|
+
<% if current_user.former_user? && current_user.teams.none? %>
|
82
|
+
</div>
|
83
|
+
<% end %>
|
84
|
+
|
85
|
+
<% end %>
|
86
|
+
|
87
|
+
<% end %>
|
88
|
+
<% end %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%= render 'account/shared/page' do |p| %>
|
2
|
+
<% p.content_for :title, t('.header', teams_possessive: possessive_string(@team.name)) %>
|
3
|
+
|
4
|
+
<% p.content_for :actions do %>
|
5
|
+
<%= link_to edit_account_team_path(@team), class: 'button-secondary button-smaller' do %>
|
6
|
+
<%= t('teams.buttons.edit') %>
|
7
|
+
<% end if can? :edit, @team %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<% p.content_for :body do %>
|
11
|
+
<%# 🚅 super scaffolding will insert new children above this line. %>
|
12
|
+
|
13
|
+
<% unless scaffolding_things_disabled? %>
|
14
|
+
<%= render 'account/shared/commentary/box' do |p| %>
|
15
|
+
<% p.content_for :content do %>
|
16
|
+
<%= render 'account/scaffolding/absolutely_abstract/creative_concepts/index', creative_concepts: @team.scaffolding_absolutely_abstract_creative_concepts.accessible_by(current_ability), hide_back: true unless scaffolding_things_disabled? %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% p.content_for :commentary do %>
|
20
|
+
<%= t('scaffolding/absolutely_abstract/creative_concepts.index.commentary').html_safe %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
25
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "teams/team", team: @team
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<%= form_for [:account, user], html: {id: dom_id(user, :details), class: 'form'} do |form| %>
|
2
|
+
<% with_field_settings form: form do %>
|
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
|
+
<div class="sm:col-span-1">
|
9
|
+
<%= render 'shared/fields/text_field', method: :first_name %>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<div class="sm:col-span-1">
|
13
|
+
<%= render 'shared/fields/text_field', method: :last_name %>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<% if cloudinary_enabled? %>
|
17
|
+
<div class="sm:col-span-2">
|
18
|
+
<%= render 'shared/fields/cloudinary_image', method: :profile_photo_id %>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<div class="sm:col-span-2">
|
23
|
+
<%= render 'shared/fields/super_select', method: :time_zone,
|
24
|
+
choices: time_zone_options_for_select(user.time_zone, nil, ActiveSupport::TimeZone),
|
25
|
+
other_options: {search: true} %>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<% if multiple_locales? %>
|
29
|
+
<div class="sm:col-span-2">
|
30
|
+
<%= render 'shared/fields/buttons', method: :locale, options: {"": t("locale.default")}.merge(t("locale.locales")) %>
|
31
|
+
</div>
|
32
|
+
<% end %>
|
33
|
+
</div>
|
34
|
+
<% end %>
|
35
|
+
|
36
|
+
<div class="buttons">
|
37
|
+
<%= form.submit t('.buttons.update_profile'), class: "button" %>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<%= render 'account/shared/page' do |p| %>
|
2
|
+
<% p.content_for :title, t('.section') %>
|
3
|
+
<% p.content_for :body do %>
|
4
|
+
<%= form_for [:account, @user] do |form| %>
|
5
|
+
<%= render 'account/shared/forms/errors', form: form %>
|
6
|
+
<% end if @user.errors.any? %>
|
7
|
+
|
8
|
+
<div class="grid grid-cols-1 gap-y gap-x-8 xl:grid-cols-2">
|
9
|
+
<div class="xl:col-span-1 space-y-8">
|
10
|
+
<%= render 'account/shared/box', divider: true do |p| %>
|
11
|
+
<% p.content_for :title, t('.profile.header') %>
|
12
|
+
<% p.content_for :description, t('.profile.description') %>
|
13
|
+
<% p.content_for :body do %>
|
14
|
+
<%= render "account/users/form", user: @user %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<% if two_factor_authentication_enabled? %>
|
19
|
+
<div id="two-factor">
|
20
|
+
<%= render partial: "devise/registrations/two_factor" %>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<div class="xl:col-span-1 space-y-8">
|
26
|
+
<%= render 'account/oauth/stripe_accounts/index', context: @user, stripe_accounts: @user.oauth_stripe_accounts if stripe_enabled? %>
|
27
|
+
<% # 🚅 super scaffolding will insert new oauth providers above this line. %>
|
28
|
+
|
29
|
+
<%= render 'account/shared/box', divider: true do |p| %>
|
30
|
+
<% p.content_for :title, t('.password.header') %>
|
31
|
+
<% p.content_for :body do %>
|
32
|
+
<% within_fields_namespace(:update_self) do %>
|
33
|
+
<%= form_for [:account, @user], html: {id: dom_id(@user, :password), class: 'form'} do |form| %>
|
34
|
+
<% with_field_settings form: form do %>
|
35
|
+
<%= render 'shared/fields/password_field', method: :current_password %>
|
36
|
+
<%= render 'shared/fields/password_field', method: :password %>
|
37
|
+
<%= render 'shared/fields/password_field', method: :password_confirmation %>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<div class="buttons">
|
41
|
+
<%= form.submit t('.buttons.update_password'), class: "button" %>
|
42
|
+
</div>
|
43
|
+
<% end %>
|
44
|
+
<% end %>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
<% end %>
|
50
|
+
<% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="element-wrapper">
|
2
|
+
<h6 class="element-header"><%= t('.section') %></h6>
|
3
|
+
<%= render 'account/shared/notices' %>
|
4
|
+
<div class="padded-lg">
|
5
|
+
|
6
|
+
<div class="alert alert-warning">
|
7
|
+
This is a placeholder view. It serves no purpose by default in Bullet Train,
|
8
|
+
but it allows you to use Super Scaffolding for models that fall under a <code>User</code>
|
9
|
+
instead of a <code>Team</code>. In our experience these types of models are quite
|
10
|
+
rare, so please use this sparingly, but if you're using this, you've probably
|
11
|
+
chatted with us about it.
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<%# 🚅 super scaffolding will insert new children above this line. %>
|
15
|
+
|
16
|
+
</div>
|
17
|
+
</div>
|
@@ -0,0 +1,69 @@
|
|
1
|
+
en:
|
2
|
+
invitations: &invitations
|
3
|
+
label: &label Invitations
|
4
|
+
breadcrumbs:
|
5
|
+
label: *label
|
6
|
+
buttons: &buttons
|
7
|
+
new: Invite a New Team Member
|
8
|
+
create: Create Invitation
|
9
|
+
update: Update Invitation
|
10
|
+
destroy: Cancel
|
11
|
+
join_team: 'Join %{team_name}'
|
12
|
+
logout: 'Logout'
|
13
|
+
confirmations:
|
14
|
+
destroy: Are you sure you want cancel the invitation to %{invitation_name}? The invitation they've received will no longer work. This can't be undone.
|
15
|
+
fields: &fields
|
16
|
+
email:
|
17
|
+
name: &email Email Address
|
18
|
+
label: *email
|
19
|
+
heading: *email
|
20
|
+
roles: &role_ids
|
21
|
+
name: &roles Special Privileges
|
22
|
+
label: *roles
|
23
|
+
heading: *roles
|
24
|
+
role_ids: *role_ids
|
25
|
+
# 🚅 super scaffolding will insert new fields above this line.
|
26
|
+
created_at:
|
27
|
+
name: &created_at Sent
|
28
|
+
heading: *created_at
|
29
|
+
index:
|
30
|
+
section: "Invitations for %{team_name}"
|
31
|
+
header: Team Member Invitations
|
32
|
+
description: We've sent the following invitations.
|
33
|
+
fields: *fields
|
34
|
+
buttons: *buttons
|
35
|
+
show:
|
36
|
+
join_team: 'Join %{team_name}'
|
37
|
+
header: Team Invitation
|
38
|
+
has_invited: "<b>%{user_name}</b> has invited you to join %{team_name}."
|
39
|
+
alert: "This invitation was emailed to <b>%{invitation_email}</b>, but you're currently signed in as <b>%{user_email}</b>."
|
40
|
+
you_can: "You can either:"
|
41
|
+
accept_the_invitation: "Accept the invitation below and you'll join the team as <b>%{user_email}</b>."
|
42
|
+
sign_out: "Sign out below, re-click the link in your email, and either sign into another account or create a new account."
|
43
|
+
fields: *fields
|
44
|
+
buttons: *buttons
|
45
|
+
form: &form
|
46
|
+
invite_as: 'Invite as %{role_key}'
|
47
|
+
buttons: *buttons
|
48
|
+
new:
|
49
|
+
section: New Invitation for %{team_name}
|
50
|
+
header: New Invitation Details
|
51
|
+
description: We'll email them a link where they can sign up to join your team.
|
52
|
+
form: *form
|
53
|
+
notifications:
|
54
|
+
edit_message: We don't support editing invitations because it introduces security problems. Please remove and recreate them.
|
55
|
+
welcome: 'Welcome to %{team_name}!'
|
56
|
+
created: 'Invitation was successfully created.'
|
57
|
+
updated: 'Invitation was successfully updated.'
|
58
|
+
destroyed: 'Invitation was successfully destroyed.'
|
59
|
+
values:
|
60
|
+
name: 'Invitation to Join %{team_name}'
|
61
|
+
account:
|
62
|
+
invitations: *invitations
|
63
|
+
activerecord:
|
64
|
+
attributes:
|
65
|
+
invitation:
|
66
|
+
email: *email
|
67
|
+
role_ids: *roles
|
68
|
+
# 🚅 super scaffolding will insert new activerecord attributes above this line.
|
69
|
+
created_at: *created_at
|
@@ -0,0 +1,42 @@
|
|
1
|
+
en:
|
2
|
+
memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments: &scaffolding_completely_concrete_tangible_things_reassignments
|
3
|
+
label: &label Tangible Things Reassignments
|
4
|
+
breadcrumbs:
|
5
|
+
label: *label
|
6
|
+
buttons: &buttons
|
7
|
+
new: Reassign to Another Team Member
|
8
|
+
create: Reassign Tangible Things
|
9
|
+
fields: &fields
|
10
|
+
membership_ids:
|
11
|
+
name: &membership_ids Target Members
|
12
|
+
label: Who should %{memberships_possessive} Tangible Things be reassigned to?
|
13
|
+
heading: *membership_ids
|
14
|
+
help: You can reassign to multiple team members. You can leave this blank to simply unassign Tangible Things from %{membership_name}.
|
15
|
+
invite_help: You can invite new team members by entering their email address and hitting <kbd>enter</kbd>.
|
16
|
+
# 🚅 super scaffolding will insert new fields above this line.
|
17
|
+
index:
|
18
|
+
section: "%{memberships_possessive} Tangible Things Reassignments"
|
19
|
+
contexts:
|
20
|
+
membership:
|
21
|
+
header: Tangible Things Reassignments
|
22
|
+
description: Below is a list of Tangible Things Reassignments that have been added to %{membership_name}. You can manage them with the options below.
|
23
|
+
fields: *fields
|
24
|
+
buttons: *buttons
|
25
|
+
form: &form
|
26
|
+
buttons: *buttons
|
27
|
+
new:
|
28
|
+
section: "Reassign %{memberships_possessive} Tangible Things"
|
29
|
+
header: Reassign Tangible Things
|
30
|
+
description: This will unassign all Tangible Things currently assigned to %{membership_name} and assign them to whichever team members are specified below.
|
31
|
+
form: *form
|
32
|
+
notifications:
|
33
|
+
created: Tangible Things were successfully reassigned.
|
34
|
+
account:
|
35
|
+
memberships:
|
36
|
+
reassignments:
|
37
|
+
scaffolding_completely_concrete_tangible_things_reassignments: *scaffolding_completely_concrete_tangible_things_reassignments
|
38
|
+
activerecord:
|
39
|
+
attributes:
|
40
|
+
memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignment:
|
41
|
+
membership_ids: *membership_ids
|
42
|
+
# 🚅 super scaffolding will insert new activerecord attributes above this line.
|