bullet_train 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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.