bullet_train 1.0.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.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/config/bullet_train_manifest.js +0 -0
  6. data/app/controllers/account/invitations_controller.rb +146 -0
  7. data/app/controllers/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments_controller.rb +83 -0
  8. data/app/controllers/account/memberships_controller.rb +132 -0
  9. data/app/controllers/account/onboarding/user_details_controller.rb +63 -0
  10. data/app/controllers/account/onboarding/user_email_controller.rb +65 -0
  11. data/app/controllers/account/teams_controller.rb +122 -0
  12. data/app/controllers/account/users_controller.rb +59 -0
  13. data/app/helpers/account/invitations_helper.rb +2 -0
  14. data/app/helpers/account/memberships_helper.rb +9 -0
  15. data/app/helpers/account/teams_helper.rb +80 -0
  16. data/app/helpers/account/users_helper.rb +81 -0
  17. data/app/helpers/invitation_only_helper.rb +10 -0
  18. data/app/helpers/invitations_helper.rb +17 -0
  19. data/app/models/invitation.rb +73 -0
  20. data/app/models/membership.rb +164 -0
  21. data/app/models/memberships/reassignments/assignment.rb +12 -0
  22. data/app/models/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignment.rb +38 -0
  23. data/app/models/memberships/reassignments.rb +5 -0
  24. data/app/models/team.rb +81 -0
  25. data/app/models/user.rb +191 -0
  26. data/app/views/account/invitations/_breadcrumbs.html.erb +9 -0
  27. data/app/views/account/invitations/_form.html.erb +49 -0
  28. data/app/views/account/invitations/_invitation.json.jbuilder +7 -0
  29. data/app/views/account/invitations/index.json.jbuilder +1 -0
  30. data/app/views/account/invitations/new.html.erb +12 -0
  31. data/app/views/account/invitations/show.html.erb +30 -0
  32. data/app/views/account/invitations/show.json.jbuilder +1 -0
  33. data/app/views/account/memberships/_breadcrumbs.html.erb +8 -0
  34. data/app/views/account/memberships/_form.html.erb +45 -0
  35. data/app/views/account/memberships/_index.html.erb +66 -0
  36. data/app/views/account/memberships/_menu_item.html.erb +8 -0
  37. data/app/views/account/memberships/_tombstones.html.erb +59 -0
  38. data/app/views/account/memberships/edit.html.erb +22 -0
  39. data/app/views/account/memberships/index.html.erb +7 -0
  40. data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/_breadcrumbs.html.erb +10 -0
  41. data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/_form.html.erb +24 -0
  42. data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/_scaffolding_completely_concrete_tangible_things_reassignment.json.jbuilder +8 -0
  43. data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/index.json.jbuilder +1 -0
  44. data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/new.html.erb +11 -0
  45. data/app/views/account/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments/show.json.jbuilder +1 -0
  46. data/app/views/account/memberships/show.html.erb +60 -0
  47. data/app/views/account/onboarding/user_details/edit.html.erb +72 -0
  48. data/app/views/account/onboarding/user_email/edit.html.erb +33 -0
  49. data/app/views/account/teams/_breadcrumbs.html.erb +11 -0
  50. data/app/views/account/teams/_form.html.erb +22 -0
  51. data/app/views/account/teams/_index.html.erb +33 -0
  52. data/app/views/account/teams/_menu_item.html.erb +8 -0
  53. data/app/views/account/teams/_team.json.jbuilder +9 -0
  54. data/app/views/account/teams/edit.html.erb +12 -0
  55. data/app/views/account/teams/index.html.erb +6 -0
  56. data/app/views/account/teams/index.json.jbuilder +1 -0
  57. data/app/views/account/teams/new.html.erb +88 -0
  58. data/app/views/account/teams/show.html.erb +25 -0
  59. data/app/views/account/teams/show.json.jbuilder +1 -0
  60. data/app/views/account/users/_breadcrumbs.html.erb +4 -0
  61. data/app/views/account/users/_form.html.erb +39 -0
  62. data/app/views/account/users/edit.html.erb +50 -0
  63. data/app/views/account/users/show.html.erb +17 -0
  64. data/config/locales/en/invitations.en.yml +69 -0
  65. data/config/locales/en/memberships/reassignments/scaffolding_completely_concrete_tangible_things_reassignments.en.yml +42 -0
  66. data/config/locales/en/memberships.en.yml +99 -0
  67. data/config/locales/en/onboarding/user_details.en.yml +11 -0
  68. data/config/locales/en/onboarding/user_email.en.yml +13 -0
  69. data/config/locales/en/teams.en.yml +85 -0
  70. data/config/locales/en/users.en.yml +110 -0
  71. data/config/routes.rb +2 -0
  72. data/db/migrate/20161115160419_devise_create_users.rb +41 -0
  73. data/db/migrate/20161116003852_add_api_key_to_user.rb +6 -0
  74. data/db/migrate/20161117154605_create_teams.rb +10 -0
  75. data/db/migrate/20161117154709_create_memberships.rb +11 -0
  76. data/db/migrate/20161203193930_add_current_team_to_user.rb +5 -0
  77. data/db/migrate/20161204234150_create_invitations.rb +11 -0
  78. data/db/migrate/20161205154821_add_team_to_invitation.rb +5 -0
  79. data/db/migrate/20161205164613_add_admin_to_invitation.rb +5 -0
  80. data/db/migrate/20170908205756_add_names_to_user.rb +6 -0
  81. data/db/migrate/20170915215309_add_team_to_thing.rb +5 -0
  82. data/db/migrate/20171105001408_remove_api_key_from_user.rb +6 -0
  83. data/db/migrate/20180326124105_add_timezone_to_user.rb +5 -0
  84. data/db/migrate/20180902142350_create_membership_roles.rb +10 -0
  85. data/db/migrate/20180902143758_remove_admin_from_membership.rb +5 -0
  86. data/db/migrate/20180902154611_create_invitation_roles.rb +10 -0
  87. data/db/migrate/20180902154652_migrate_admin_flag_on_invitations.rb +14 -0
  88. data/db/migrate/20180902195848_remove_admin_from_invitation.rb +5 -0
  89. data/db/migrate/20180903101707_add_last_seen_at_to_users.rb +5 -0
  90. data/db/migrate/20190321203224_add_profile_photo_id_to_user.rb +5 -0
  91. data/db/migrate/20190519230202_add_ability_cache_to_user.rb +5 -0
  92. data/db/migrate/20190628194704_add_last_notification_email_sent_at_to_user.rb +5 -0
  93. data/db/migrate/20200211034208_add_invitation_to_membership.rb +5 -0
  94. data/db/migrate/20200211044616_drop_invitation_roles_table.rb +10 -0
  95. data/db/migrate/20200213052748_add_former_user_fields_to_membership.rb +8 -0
  96. data/db/migrate/20200213235037_add_former_user_to_user.rb +7 -0
  97. data/db/migrate/20200219013834_add_added_by_to_membership.rb +5 -0
  98. data/db/migrate/20200219015116_rename_from_user_to_from_membership.rb +5 -0
  99. data/db/migrate/20200726222314_add_being_destroyed_to_team.rb +5 -0
  100. data/db/migrate/20200727171308_add_devise_two_factor_to_users.rb +9 -0
  101. data/db/migrate/20200727175949_add_devise_two_factor_backupable_to_users.rb +5 -0
  102. data/db/migrate/20210304133200_add_time_zone_to_team.rb +5 -0
  103. data/db/migrate/20210816072419_add_locale_to_users.rb +5 -0
  104. data/db/migrate/20210816072508_add_locale_to_teams.rb +5 -0
  105. data/db/migrate/20211020200855_add_doorkeeper_application_to_memberships.rb +5 -0
  106. data/db/migrate/20211027002944_add_doorkeeper_application_to_users.rb +5 -0
  107. data/lib/bullet_train/engine.rb +4 -0
  108. data/lib/bullet_train/version.rb +3 -0
  109. data/lib/bullet_train.rb +6 -0
  110. data/lib/tasks/bullet_train_tasks.rake +4 -0
  111. 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,8 @@
1
+ <%= render 'account/shared/menu/item', {
2
+ url: main_app.polymorphic_path([:account, current_team]),
3
+ label: t('menus.main.labels.dashboard'),
4
+ } do |p| %>
5
+ <% p.content_for :icon do %>
6
+ <i class="fal fa-home-lg-alt ti ti-home"></i>
7
+ <% end %>
8
+ <% end %>
@@ -0,0 +1,9 @@
1
+ json.extract! team,
2
+ :id,
3
+ :name,
4
+ :time_zone,
5
+ :locale,
6
+ # 🚅 super scaffolding will insert new fields above this line.
7
+ :created_at,
8
+ :updated_at
9
+ json.url account_team_url(team, format: :json)
@@ -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,6 @@
1
+ <%= render 'account/shared/page' do |p| %>
2
+ <% p.content_for :title, t('.section') %>
3
+ <% p.content_for :body do %>
4
+ <%= render 'index', creative_concepts: @creative_concepts %>
5
+ <% end %>
6
+ <% 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,4 @@
1
+ <%= render 'account/shared/breadcrumb', label: 'Your Account', first: true %>
2
+ <% if action_name == 'edit' && controller_name == 'users' %>
3
+ <%= render 'account/shared/breadcrumb', label: 'Settings' %>
4
+ <% end %>
@@ -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.