bullet_train 1.2.26 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/account/controllers/base.rb +2 -0
  3. data/app/controllers/concerns/account/memberships/controller_base.rb +2 -1
  4. data/app/controllers/concerns/account/teams/controller_base.rb +1 -1
  5. data/app/controllers/concerns/sessions/controller_base.rb +35 -0
  6. data/app/controllers/sessions_controller.rb +0 -32
  7. data/app/helpers/account/dates_helper.rb +11 -31
  8. data/app/helpers/account/markdown_helper.rb +8 -1
  9. data/app/helpers/account/users_helper.rb +43 -24
  10. data/app/helpers/attributes_helper.rb +7 -22
  11. data/app/helpers/invitation_only_helper.rb +9 -1
  12. data/app/javascript/controllers/bulk_actions_controller.js +1 -0
  13. data/app/models/billing/mock_limiter.rb +1 -1
  14. data/app/models/concerns/memberships/base.rb +17 -0
  15. data/app/models/concerns/records/base.rb +3 -1
  16. data/app/models/concerns/teams/base.rb +4 -8
  17. data/app/models/concerns/users/base.rb +15 -1
  18. data/app/views/account/memberships/_index.html.erb +1 -1
  19. data/app/views/account/onboarding/user_details/edit.html.erb +1 -0
  20. data/app/views/account/users/_form.html.erb +6 -4
  21. data/app/views/devise/registrations/new.html.erb +1 -1
  22. data/app/views/layouts/docs.html.erb +15 -3
  23. data/app/views/layouts/public.html.erb +31 -0
  24. data/config/locales/en/base.yml +9 -0
  25. data/config/locales/en/memberships.en.yml +3 -0
  26. data/config/locales/en/users.en.yml +5 -0
  27. data/docs/application-hash.md +25 -0
  28. data/docs/billing/stripe.md +3 -3
  29. data/docs/billing/usage.md +7 -7
  30. data/docs/field-partials/buttons.md +4 -4
  31. data/docs/field-partials/date-related-fields.md +13 -0
  32. data/docs/field-partials/file-field.md +1 -2
  33. data/docs/field-partials/super-select.md +23 -4
  34. data/docs/field-partials.md +24 -11
  35. data/docs/font-awesome-pro.md +1 -1
  36. data/docs/index.md +9 -8
  37. data/docs/indirection.md +5 -1
  38. data/docs/overriding.md +1 -1
  39. data/docs/seeds.md +3 -3
  40. data/docs/super-scaffolding/delegated-types.md +27 -24
  41. data/docs/super-scaffolding/options.md +24 -0
  42. data/docs/super-scaffolding/sortable.md +1 -1
  43. data/docs/super-scaffolding.md +7 -6
  44. data/docs/testing.md +1 -1
  45. data/docs/themes.md +4 -4
  46. data/docs/tunneling.md +2 -2
  47. data/docs/upgrades.md +7 -7
  48. data/docs/zapier.md +1 -1
  49. data/lib/bullet_train/configuration.rb +9 -3
  50. data/lib/bullet_train/resolver.rb +11 -6
  51. data/lib/bullet_train/version.rb +1 -1
  52. data/lib/bullet_train.rb +13 -8
  53. data/lib/tasks/bullet_train_tasks.rake +30 -0
  54. metadata +23 -6
  55. data/README.md +0 -29
@@ -46,6 +46,8 @@ en:
46
46
  typing_search: Start typing search...
47
47
  sidebar: Sidebar
48
48
  creator: Bullet Train, Inc.
49
+ time_ago: "%{time} ago"
50
+ never: Never
49
51
  buttons:
50
52
  other: Other
51
53
  debug: Debug
@@ -80,6 +82,13 @@ en:
80
82
  timestamp_unavailable: Never
81
83
  date: '%m/%d/%Y'
82
84
  date_and_time: '%m/%d/%Y %l:%M %p'
85
+ file_fields:
86
+ download: Download File
87
+ download_current: Download Current Document
88
+ remove: Remove Current Document
89
+ upload: Upload New Document
90
+ bulk_select:
91
+ all: All
83
92
 
84
93
  menus:
85
94
  main:
@@ -34,6 +34,9 @@ en:
34
34
  user_profile_photo_id:
35
35
  name: &user_profile_photo_id Profile Photo
36
36
  label: *user_profile_photo_id
37
+ user_profile_photo:
38
+ name: &user_profile_photo Profile Photo
39
+ label: *user_profile_photo
37
40
  role_ids:
38
41
  name: &roles Special Privileges
39
42
  label: *roles
@@ -56,6 +56,10 @@ en:
56
56
  _: &profile_photo_id Profile Photo
57
57
  label: *profile_photo_id
58
58
  heading: *profile_photo_id
59
+ profile_photo:
60
+ _: &profile_photo Profile Photo
61
+ label: *profile_photo
62
+ heading: *profile_photo
59
63
  current_password:
60
64
  label: Current Password
61
65
  password:
@@ -116,6 +120,7 @@ en:
116
120
  last_name: *last_name
117
121
  email: *email
118
122
  profile_photo_id: *profile_photo_id
123
+ profile_photo: *profile_photo
119
124
  time_zone: *time_zone
120
125
  locale: *locale
121
126
  # 🚅 super scaffolding will insert new activerecord attributes above this line.
@@ -0,0 +1,25 @@
1
+ ## `ApplicationHash`
2
+ [Webhooks::Outgoing::EventType](https://github.com/bullet-train-co/bullet_train-core/blob/main/bullet_train-outgoing_webhooks/app/models/webhooks/outgoing/event_type.rb) inherits a class called [ApplicationHash](https://github.com/bullet-train-co/bullet_train/blob/main/app/models/application_hash.rb) which includes helpful methods from [ActiveHash](https://github.com/active-hash/active_hash).
3
+
4
+ ActiveHash itself is a simple base class that allows you to use a Ruby hash as a readonly datasource for an ActiveRecord-like model.
5
+
6
+ For webhooks in Bullet Train, this means that we can handle `Webhooks::Outgoing::EventType` similar to an ActiveRecord model even though it doesn't have a table in the database like models usually do, making it easier to order and utilize data like this in the context of a Rails application.
7
+
8
+ ```
9
+ > rails c
10
+ irb(main):001:0> Scaffolding::AbsolutelyAbstract::CreativeConcept.all.class
11
+ => Scaffolding::AbsolutelyAbstract::CreativeConcept::ActiveRecord_Relation
12
+ irb(main):002:0> Webhooks::Outgoing::EventType.all.class
13
+ => ActiveHash::Relation
14
+
15
+ # An example from the EndpointSupport module
16
+ def event_types
17
+ event_type_ids.map { |id| Webhooks::Outgoing::EventType.find(id) }
18
+ end
19
+ ```
20
+
21
+ Now that we can use `Webhooks::Outgoing::EventType` like an ActiveRecord model, we can use methods like `find`, as well as declare associations like `belongs_to` for any models that inherit `ApplicationHash`.
22
+
23
+ Also, because the event types are declared in a [YAML file](https://github.com/bullet-train-co/bullet_train/blob/main/config/models/webhooks/outgoing/event_types.yml), all you have to do is add attributes there to add changes to your ApplicationHash data.
24
+
25
+ Refer to the Active Hash [repository](https://github.com/active-hash/active_hash) for more details.
@@ -14,7 +14,7 @@ First, [purchase Bullet Train Billing for Stripe](https://buy.stripe.com/28o8zg4
14
14
 
15
15
  You'll need to specify both Ruby gems in your `Gemfile`, since we have to specify a private source for both:
16
16
 
17
- ```
17
+ ```ruby
18
18
  source "https://YOUR_TOKEN_HERE@gem.fury.io/bullettrain" do
19
19
  gem "bullet_train-billing"
20
20
  gem "bullet_train-billing-stripe"
@@ -64,7 +64,7 @@ Bullet Train defines subscription plans and pricing options in `config/models/bi
64
64
 
65
65
  Edit `config/application.yml` and add your new Stripe secret key to the file:
66
66
 
67
- ```
67
+ ```yaml
68
68
  STRIPE_SECRET_KEY: sk_0CJw2Iu5wwIKXUDdqphrt2zFZyOCH
69
69
  ```
70
70
 
@@ -103,7 +103,7 @@ Ensure you've completed the steps from [HTTP Tunneling with ngrok](/docs/tunneli
103
103
 
104
104
  After creating the webhook endpoint, click "reveal" under the heading "signing secret". Copy the `whsec_...` value into your `config/application.yml` like so:
105
105
 
106
- ```
106
+ ```yaml
107
107
  STRIPE_WEBHOOKS_ENDPOINT_SECRET: whsec_vchvkw3hrLK7SmUiEenExipUcsCgahf9
108
108
  ```
109
109
 
@@ -6,7 +6,7 @@ Bullet Train provides a holistic method for defining model-based usage limits in
6
6
 
7
7
  ### 1. Purchase Bullet Train Pro
8
8
 
9
- First, [purchase Bullet Train Pro](https://buy.stripe.com/aEU7vc4dBfHtfO89AV). Once you've completed this process, you'll be issued a private token for the Bullet Train Pro package server. The process is currently completed manually, so you may have to way a little to receive your keys.
9
+ First, [purchase Bullet Train Pro](https://buy.stripe.com/aEU7vc4dBfHtfO89AV). Once you've completed this process, you'll be issued a private token for the Bullet Train Pro package server. The process is currently completed manually, so you may have to wait a little to receive your keys.
10
10
 
11
11
  ### 2. Install the Package
12
12
 
@@ -51,21 +51,21 @@ There are two concerns that need to be added to your application models.
51
51
 
52
52
  The first concern is `Billing::UsageSupport` and it allows tracking of usage of verbs on the models you want to support tracking usage on. It is recommended to add this capability to all models, so you can add this.
53
53
 
54
- ```
54
+ ```ruby
55
55
  # app/models/application_record.rb
56
56
 
57
57
  class ApplicationRecord
58
- include Billing::Usage
58
+ include Billing::UsageSupport
59
59
  end
60
60
  ```
61
61
 
62
- The second concern is `Billing::HasTrackers` and it allows any model to hold the usage tracking. This is usually done on the `Team` model.
62
+ The second concern is `Billing::Usage::HasTrackers` and it allows any model to hold the usage tracking. This is usually done on the `Team` model.
63
63
 
64
- ```
64
+ ```ruby
65
65
  # app/models/team.rb
66
66
 
67
67
  class Team
68
- include Billing::HasTrackers
68
+ include Billing::Usage::HasTrackers
69
69
  end
70
70
  ```
71
71
 
@@ -191,7 +191,7 @@ current_limits.exhausted?(Blogs::Post, :soft)
191
191
 
192
192
  If you want to present an error or warning to the user based on their usage, there themed alert partials that can be displayed in your views. These partials can be rendered via the path `shared/limits/error` and `shared/limits/warning` respectively.
193
193
 
194
- ```ruby
194
+ ```erb
195
195
  <%= render "shared/limits/warning", model: model.class %>
196
196
 
197
197
  <%= render "shared/limits/error", action: :create, model: model.class, count: 1, cancel_path: cancel_path %>
@@ -4,13 +4,13 @@
4
4
 
5
5
  If you invoke the field partial in `app/views/account/some_class_name/_form.html.erb` like so:
6
6
 
7
- ```
7
+ ```erb
8
8
  <%= render 'shared/fields/buttons', form: form, method: :enabled %>
9
9
  ```
10
10
 
11
11
  You can define the available buttons in `config/locales/en/some_class_name.en.yml` like so:
12
12
 
13
- ```
13
+ ```yaml
14
14
  en:
15
15
  some_class_name:
16
16
  fields:
@@ -27,7 +27,7 @@ en:
27
27
 
28
28
  You can generate the available buttons using a collection of database objects by passing the `options` option like so:
29
29
 
30
- ```
30
+ ```erb
31
31
  <%= render 'shared/fields/buttons', form: form, method: :category_id,
32
32
  options: Category.all.map { |category| [category.id, category.label_string] } %>
33
33
  ```
@@ -36,7 +36,7 @@ You can generate the available buttons using a collection of database objects by
36
36
 
37
37
  You can allow multiple buttons to be selected using the `multiple` option, like so:
38
38
 
39
- ```
39
+ ```erb
40
40
  <%= render 'shared/fields/buttons', form: form, method: :category_ids,
41
41
  options: Category.all.map { |category| [category.id, category.label_string] }, multiple: true %>
42
42
  ```
@@ -0,0 +1,13 @@
1
+ # Customizing `date_field` and `date_and_time_field` Field Partials
2
+
3
+ You can customize the format in which your `Date` and `DateTime` fields appear by passing the `format` option to your render calls. You can also use `date_format` and `time_format` to accomplish the same thing.
4
+
5
+ ```erb
6
+ <%# For Date objects %>
7
+ <%= render 'shared/attributes/date', attribute: :date_test, format: "%m/%d" %>
8
+ <%= render 'shared/attributes/date', attribute: :date_test, date_format: "%m/%d" %>
9
+
10
+ <%# For DateTime objects %>
11
+ <%= render 'shared/attributes/date_and_time', attribute: :date_time_test, format: "%m/%d %I %p" %>
12
+ <%= render 'shared/attributes/date_and_time', attribute: :date_time_test, date_format: "%m/%d", time_format: "%I %p" %>
13
+ ```
@@ -8,8 +8,7 @@ In addition, Bullet Train has integrated the direct-uploads feature of Active St
8
8
 
9
9
  ## Example
10
10
 
11
- Add a 'document' file as an attachment to a `Post` model:
12
-
11
+ The following steps illustrate how to add a `document` file attachment to a `Post` model.
13
12
  Add the following to `app/models/post.rb`:
14
13
 
15
14
  ```ruby
@@ -1,6 +1,8 @@
1
+ Note: before you attempt to manually wire up a `super_select` field, note that Super Scaffolding will automatically do that for your models. See [Super Scoffolding](/docs/super-scaffolding.md) docs, section 4, for an example. And make sure Super Scoffolding doesn't automatically do what you're trying to do.
2
+
1
3
  # Examples for the `super_select` Field Partial
2
4
 
3
- The `super_select` partial provides a wonderful default UI (in contrast to the vanilla browser experience for this, which is horrible) with optional search and multi-select functionality out-of-the-box. It invokes the [Select2][select2] library to provide you these features.
5
+ The `super_select` partial provides a wonderful default UI (in contrast to the vanilla browser experience for select boxes, which is horrible) with optional search and multi-select functionality out-of-the-box. It invokes the [Select2][select2] library to provide you these features.
4
6
 
5
7
  ## Define Available Buttons via Localization Yaml
6
8
 
@@ -28,7 +30,9 @@ You can define the available options in `config/locales/en/some_class_name.en.ym
28
30
  Although it's recommended to define any static list of choices in the localization Yaml file (so your application remains easy to translate into other languages), you can also specify these choices using the `choices` option from the underlying select form field helper:
29
31
 
30
32
  <pre><code><%= render 'shared/fields/super_select', form: form, method: :response_behavior,
31
- choices: [['Immediately', 'immediate'], ['After a 10 minute delay', 'after_10_minutes'] ["Doesn't respond", 'disabled']] %></code></pre>
33
+ choices: [['Immediately', 'immediate'],
34
+ ['After a 10 minute delay', 'after_10_minutes'],
35
+ ["Doesn't respond", 'disabled']] %></code></pre>
32
36
 
33
37
  ## Generate Choices Programmatically
34
38
 
@@ -88,7 +92,7 @@ All events dispatched from the `super_select` partial are [Select2's jQuery even
88
92
  | select2:clearing | $select2:clearing |
89
93
  | select2:clear | $select2:clear |
90
94
 
91
- For example, catching the `$change` events in a parent `dependent-form-fields` Stimulus controller with a single `updateDependentFields` method would look like this:
95
+ For example, the view template for catching the `$change` events in a parent `dependent-form-fields` using a Stimulus controller with a single `updateDependentFields` method would look like this:
92
96
 
93
97
  <pre><code>&lt;div data-controller="dependent-form-fields"&gt;
94
98
  &lt;div data-action="$change->dependent-form-fields#updateDependentFields"&gt;
@@ -124,4 +128,19 @@ export default class extends Controller {
124
128
  </code></pre>
125
129
 
126
130
  [select2]: https://select2.org
127
- [select2_events]: https://select2.org/programmatic-control/events
131
+ [select2_events]: https://select2.org/programmatic-control/events
132
+
133
+ ## Options
134
+ Select2 has different options available which you can check [here](https://select2.org/configuration/options-api).
135
+
136
+ You can pass these options to the super select partial like so:
137
+ ```erb
138
+ <%= render 'shared/fields/super_select', method: :project,
139
+ select2_options: {
140
+ allowClear: true,
141
+ placeholder: 'Your Custom Placeholder'
142
+ }
143
+ %>
144
+ ```
145
+
146
+ *Passing options like this doesn't allow JS callbacks or functions to be used, so you must extend the Stimulus controller and add options to the `optionsOverride` getter if you want to do so.
@@ -23,13 +23,13 @@ Each field partial can optionally include whichever of the following are require
23
23
  ## Basic Usage
24
24
  The form field partials are designed to be a 1:1 match for [the native Rails form field helpers](https://guides.rubyonrails.org/form_helpers.html) developers are already used to using. For example, consider the following basic Rails form field helper invocation:
25
25
 
26
- ```
26
+ ```erb
27
27
  <%= form.text_field :text_field_value, autofocus: true %>
28
28
  ```
29
29
 
30
30
  Using the field partials, the same field would be implemented as follows:
31
31
 
32
- ```
32
+ ```erb
33
33
  <%= render 'shared/fields/text_field', form: form, method: :text_field_value, options: {autofocus: true} %>
34
34
  ```
35
35
 
@@ -52,7 +52,7 @@ Because Bullet Train field partials have more responsibilities than the underlyi
52
52
 
53
53
  For example, to suppress a label on any field, we can use the `hide_label` option like so:
54
54
 
55
- ```
55
+ ```erb
56
56
  <%= render 'shared/fields/text_field', form: form, method: :text_field_value, other_options: {hide_label: true} %>
57
57
  ```
58
58
 
@@ -67,7 +67,7 @@ For example, to suppress a label on any field, we can use the `hide_label` optio
67
67
  ## Reducing Repetition
68
68
  When you're including multiple fields, you can DRY up redundant settings (e.g. `form: form`) like so:
69
69
 
70
- ```
70
+ ```erb
71
71
  <% with_field_settings form: form do %>
72
72
  <%= render 'shared/fields/text_field', method: :text_field_value, options: {autofocus: true} %>
73
73
  <%= render 'shared/fields/buttons', method: :button_value %>
@@ -76,34 +76,37 @@ When you're including multiple fields, you can DRY up redundant settings (e.g. `
76
76
  ```
77
77
 
78
78
  ## Field partials that integrate with third-party service providers
79
- - `cloudinary` makes it trivial to upload photos and images to [Cloudinary](https://cloudinary.com) and store their resulting Cloudinary ID as an attribute of the model backing the form. To enable this field partial, sign up for Cloudinary and copy the "Cloudinary URL" they provide you with into your `config/application.yml` as `CLOUDINARY_URL`. If you use our [Heroku app.json](https://github.com/bullet-train-co/bullet_train/blob/main/app.json) to provision your production environment, this will happen in that environment automatically.
79
+ - `cloudinary_image` makes it trivial to upload photos and videos to [Cloudinary](https://cloudinary.com) and store their resulting Cloudinary ID as an attribute of the model backing the form. To enable this field partial, sign up for Cloudinary and copy the "Cloudinary URL" they provide you with into your `config/application.yml` as `CLOUDINARY_URL`. If you use our [Heroku app.json](https://github.com/bullet-train-co/bullet_train/blob/main/app.json) to provision your production environment, this will happen in that environment automatically.
80
80
 
81
81
  ## Yaml Configuration
82
82
  The localization Yaml file (where you configure label and option values for a field) is automatically generated when you run Super Scaffolding for a model. If you haven't done this yet, the localization Yaml file for `Scaffolding::CompletelyConcrete::TangibleThing` serves as a good example. Under `en.scaffolding/completely_concrete/tangible_things.fields` you'll see definitions like this:
83
83
 
84
- <pre><code>text_field_value:
84
+ ```yaml
85
+ text_field_value:
85
86
  name: &text_field_value Text Field Value
86
87
  label: *text_field_value
87
88
  heading: *text_field_value
88
- </code></pre>
89
+ ```
89
90
 
90
91
  This might look redundant at first glance, as you can see that by default the same label ("Text Field Value") is being used for both the form field label (`label`) and the heading (`heading`) of the show view and table view. It's also used when the field is referred to in a validation error message. However, having these three values defined separately gives us the flexibility of defining much more user-friendly labels in the context of a form field. In my own applications, I'll frequently configure these form field labels to be much more verbose questions (in an attempt to improve the UX), but still use the shorter label as a column header on the table view and the show view:
91
92
 
92
- <pre><code>text_field_value:
93
+ ```yaml
94
+ text_field_value:
93
95
  name: &text_field_value Text Field Value
94
96
  label: "What should the value of this text field be?"
95
97
  heading: *text_field_value
96
- </code></pre>
98
+ ```
97
99
 
98
100
  You can also configure some placeholder text (displayed in the field when in an empty state) or some inline help text (to be presented to users under the form field) like so:
99
101
 
100
- <pre><code>text_field_value:
102
+ ```yaml
103
+ text_field_value:
101
104
  name: &text_field_value Text Field Value
102
105
  label: "What should the value of this text field be?"
103
106
  heading: *text_field_value
104
107
  placeholder: "Type your response here"
105
108
  help: "The value can be anything you want it to be!"
106
- </code></pre>
109
+ ```
107
110
 
108
111
  Certain form field partials like `buttons` and `super_select` can also have their selectable options configured in this Yaml file. See their respective documentation for details, as usage varies slightly.
109
112
 
@@ -136,7 +139,17 @@ Set the data type to `jsonb` whenever passing the `multiple` option to a new att
136
139
  > bin/super-scaffold crud Project Team multiple_buttons:buttons{multiple}
137
140
  ```
138
141
 
142
+ ## Formating `date` and `date_and_time`
143
+ After Super Scaffolding a `date` or `date_and_time` field, you can pass a format for the object like so:
144
+
145
+ ```
146
+ <%= render 'shared/attributes/date', attribute: date_object, format: :short %>
147
+ ```
148
+
149
+ Please refer to the [Ruby on Rails documentation](https://guides.rubyonrails.org/i18n.html#adding-date-time-formats) for more information.
150
+
139
151
  ## Additional Field Partials Documentation
140
152
  - [`buttons`](/docs/field-partials/buttons.md)
141
153
  - [`super_select`](/docs/field-partials/super-select.md)
142
154
  - [`file_field`](/docs/field-partials/file-field.md)
155
+ - [`date_field` and `date_and_time_field`](/docs/field-partials/date-related-fields.md)
@@ -45,6 +45,6 @@ No, that's not a typo. [That's the name of their company.](https://fortawesome.c
45
45
 
46
46
  In `app/javascript/application.js`, below `require("@icon/themify-icons/themify-icons.css")`, add:
47
47
 
48
- ```
48
+ ```js
49
49
  require("@fortawesome/fontawesome-pro/css/all.css")
50
50
  ```
data/docs/index.md CHANGED
@@ -5,13 +5,13 @@
5
5
  ## Introduction
6
6
  - [What is Bullet Train?](https://bullettrain.co) <i class="ti ti-new-window ml-2"></i>
7
7
  - [Getting Started](/docs/getting-started.md)
8
- - [Upgrading](/docs/upgrades.md)
8
+ - [Upgrades](/docs/upgrades.md)
9
9
 
10
10
  ## General Topics
11
11
  - [Domain Modeling](/docs/modeling.md)
12
12
  - [Dealing with Indirection](/docs/indirection.md)
13
13
  - [Overriding the Framework](/docs/overriding.md)
14
- - [Setting up a Tunnel](/docs/tunneling.md)
14
+ - [Tunneling](/docs/tunneling.md)
15
15
  - [JavaScript](/docs/javascript.md)
16
16
  - [Internationalization](/docs/i18n.md)
17
17
 
@@ -20,20 +20,21 @@
20
20
  - [Action Models](/docs/action-models.md)
21
21
  - [Database Seeds](/docs/seeds.md)
22
22
  - [Test Suite](/docs/testing.md)
23
- - [Point-and-Click Test Writing](https://github.com/bullet-train-co/magic_test) <i class="ti ti-new-window ml-2"></i>
23
+ - [Magic Test: Point-and-Click Test Writing](https://github.com/bullet-train-co/magic_test) <i class="ti ti-new-window ml-2"></i>
24
24
  - [Application Options](/docs/application-options.md)
25
25
 
26
26
  ## Accounts & Teams
27
27
  - [Authentication](/docs/authentication.md)
28
28
  - [Teams](/docs/teams.md)
29
- - [Roles and Permissions](/docs/permissions.md)
29
+ - [Roles & Permissions](/docs/permissions.md)
30
30
  - [Onboarding](/docs/onboarding.md)
31
31
  - [Namespacing](/docs/namespacing.md)
32
32
 
33
- ## UI
33
+ ## User Interface
34
34
  - [Field Partials](/docs/field-partials.md)
35
35
  - [Theme Engine](/docs/themes.md)
36
- - [Partial Improvements](https://github.com/bullet-train-co/nice_partials) <i class="ti ti-new-window ml-2"></i>
36
+ - [Nice Partials](https://github.com/bullet-train-co/nice_partials) <i class="ti ti-new-window ml-2"></i>
37
+ - [Showcase](https://github.com/bullet-train-co/showcase) <i class="ti ti-new-window ml-2"></i>
37
38
 
38
39
  ## Billing
39
40
  - [Stripe](/docs/billing/stripe.md)
@@ -45,11 +46,11 @@
45
46
  - [OAuth Providers](/docs/oauth.md)
46
47
  - [Outgoing Webhooks](/docs/webhooks/outgoing.md)
47
48
  - [Incoming Webhooks](/docs/webhooks/incoming.md)
48
-
49
+
49
50
  ## Add-Ons
50
51
  - [Font Awesome Pro](/docs/font-awesome-pro.md)
51
52
 
52
- ## Production
53
+ ## Deployment
53
54
  - [Heroku](/docs/heroku.md)
54
55
  - [Desktop Applications](/docs/desktop.md)
55
56
 
data/docs/indirection.md CHANGED
@@ -24,7 +24,7 @@ If you need to modify behavior in these framework-provided classes or modules, s
24
24
 
25
25
  Even in vanilla Rails development, when you're looking at a view file, the path you see passed to a `render` call isn't the actual file name of the partial that will be rendered. This is even more true in Bullet Train where certain partial paths are [magically served from theme gems](/docs/themes.md).
26
26
 
27
- `bin/resolve` makes it easy to figure out where where a partial is being served from:
27
+ `bin/resolve` makes it easy to figure out where a partial is being served from:
28
28
 
29
29
  ```
30
30
  bin/resolve shared/box
@@ -79,6 +79,10 @@ You can see the full translation key of any string on the page by adding `?show_
79
79
 
80
80
  You can also log all the translation keys for anything being rendered to the console by adding `?log_locales=true` to the request URL. This can make it easier to copy and paste translation keys for strings that are rendered in non-selectable UI elements.
81
81
 
82
+ #### Eject all Translations to your Application
83
+
84
+ Run `rake bullet_train:themes[eject]` to put all of Bullet Train's core locales into your repository. Then you can sift through the files to keep the ones you want to customize, and remove the ones you don't need.
85
+
82
86
  #### Resolving Translation Keys with `bin/resolve`
83
87
 
84
88
  Once you have the full I18n translation key, you can use `bin/resolve` to figure out which package and file it's coming from. At that point, if you need to customize it, you can also use the `--eject` option to copy the framework for customization in your local application:
data/docs/overriding.md CHANGED
@@ -10,7 +10,7 @@ When it comes to object-oriented classes, wholesale copying framework files into
10
10
 
11
11
  For this reason, common points of extension like framework-provided models and controllers actually exist as a kind of "stub" in the local repository, but include their base functionality from framework-provided concerns, like so:
12
12
 
13
- ```
13
+ ```ruby
14
14
  class User < ApplicationRecord
15
15
  include Users::Base
16
16
 
data/docs/seeds.md CHANGED
@@ -6,7 +6,7 @@ Bullet Train introduces a new, slightly different expectation for Rails seed dat
6
6
 
7
7
  This is different than the Rails default, [as evidenced by the Rails example](https://guides.rubyonrails.org/v6.1.1/active_record_migrations.html#migrations-and-seed-data) which uses `Product.create`:
8
8
 
9
- ```
9
+ ```ruby
10
10
  5.times do |i|
11
11
  Product.create(name: "Product ##{i}", description: "A product.")
12
12
  end
@@ -16,7 +16,7 @@ end
16
16
 
17
17
  In Bullet Train applications, you would implement that same `db/seeds.rb` logic like so:
18
18
 
19
- ```
19
+ ```ruby
20
20
  5.times do |i|
21
21
    Product.find_or_create_by(name: "Product ##{i}") do |product|
22
22
  # this only happens if on a `create`.
@@ -39,7 +39,7 @@ In some cases, you may have core seed data like roles that needs to exist in eve
39
39
 
40
40
  Then in `db/seeds.rb`, you can load all of the shared core seed data at the beginning of `db/seeds.rb` and then load the environment-specific seeds only when you've specified one of those environments.
41
41
 
42
- ```
42
+ ```ruby
43
43
  load "#{Rails.root}/db/seeds/development.rb" if Rails.env.development?
44
44
  load "#{Rails.root}/db/seeds/test.rb" if Rails.env.test?
45
45
  ```