bullet_train 1.0.36 → 1.0.37

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f59fc1585c81b8c0c07c7785ef20b210f730a27fff291492f7eb4e4e59df2fb7
4
- data.tar.gz: 7324c7846dc20260b6bb41a28abb537b72bef6b7db4e8b1bf591a67f8ce12b83
3
+ metadata.gz: 48bdf85d340015182f0265ee63fbd647e731dbba5ac5ee776b0f723fd866a9ec
4
+ data.tar.gz: 405bd407266bfc304ebf33f37924419717f155aa7f899edf472f298597209e54
5
5
  SHA512:
6
- metadata.gz: ba5154d736c18eced42d347b7438c188a6cf7d41785a5a81f46d1444e856896bf039a8db1835a35be1c022f08864f5ed088ec1da9e59690958f6c5e6dbebdb39
7
- data.tar.gz: adb32cf308b9764cfb9a258031f6b8066145c795343fc9ce22a39454cfea8665d82d952d1a2ed34168a2d0028ec2217b296f6fa5072229ed0d88cc80a1e23923
6
+ metadata.gz: a10cb7ca6fc7f8c547aeaef879437267c46d9bbb6230790939246d6e56b3539dd6f55e36d9964e9ac6aa01151ad3a45d695d74624c999f91a25b83ee4bc6d178
7
+ data.tar.gz: 47a8b0c7efaefb3df5744a484b9dd9b5cc86f57f5e11e2c0585232d97039f6b035b85ada3bd8550b27b200b37005880ae045e06912e679ac0b96e4ee0740d552
data/config/routes.rb CHANGED
@@ -3,7 +3,7 @@ Rails.application.routes.draw do
3
3
  root to: "home#index"
4
4
  get "invitation" => "home#invitation", :as => "invitation"
5
5
 
6
- if Rails.env.production? ? ENV["ENABLE_DOCS"].present? : true
6
+ if Rails.env.development?
7
7
  get "docs", to: "home#docs"
8
8
  get "docs/*page", to: "home#docs"
9
9
  end
data/docs/api.md ADDED
@@ -0,0 +1,3 @@
1
+ # REST API
2
+
3
+ > TODO This section needs to be written and should probably delegate a lot of details to the README of the [Bullet Train API repository](https://github.com/bullet-train-co/bullet_train-api).
@@ -0,0 +1,13 @@
1
+ # Authentication
2
+ Bullet Train uses [Devise](https://github.com/heartcombo/devise) for authentication and we've done the work of making the related views look pretty and well-integrated with the look-and-feel of the application template.
3
+
4
+ ## Customizing Controllers
5
+ Bullet Train registers its own slightly customized registration and session controllers for Devise. If you want to customize them further, you can simply eject those controllers from the framework and override them locally, like so:
6
+
7
+ ```
8
+ $ bin/resolve RegistrationsController --eject --open
9
+ $ bin/resolve SessionsController --eject --open
10
+ ```
11
+
12
+ ## Customizing Views
13
+ You can customize Devise views using the same workflow you would use to customize any other Bullet Train views.
@@ -0,0 +1,90 @@
1
+ # Enabling Stripe Subscriptions
2
+
3
+ Bullet Train provides a base billing package and a Stripe-specific package with support for Stripe Checkout, Stripe Billing's customer portal, and incoming Stripe webhooks.
4
+
5
+ ## 1. Add the `bullet_train-billing-stripe` Ruby gem.
6
+
7
+ > TODO Add instructions about subscribing to Bullet Train Pro.
8
+
9
+ ## 2. Migrate the Database
10
+
11
+ ```
12
+ rake db:migrate
13
+ ```
14
+
15
+ ## 3. Create API Keys with Stripe
16
+
17
+ - Create a Stripe account if you don't already have one.
18
+ - Visit https://dashboard.stripe.com/apikeys.
19
+ - For your development environment, make sure you toggle the "test mode" flag to "on" in the top-right corner.
20
+ - Create a new secret key.
21
+
22
+ ## 4. Configure Stripe API Keys Locally
23
+
24
+ Edit `config/application.yml` and add your Stripe publishable key and new secret key to the file, and also tell the system to use Stripe subscriptions by default:
25
+
26
+ ```
27
+ BILLING_DEFAULT_SUBSCRIPTION: "Billing::Stripe::Subscription"
28
+ STRIPE_PUBLISHABLE_KEY: pk_0CJwz5wHlKBXxDA4VO1uEoipxQob0
29
+ STRIPE_SECRET_KEY: sk_0CJw2Iu5wwIKXUDdqphrt2zFZyOCH
30
+ ```
31
+
32
+ ## 5. Populate Stripe with Locally Configured Products
33
+
34
+ Bullet Train defines subscription plans and other purchasable add-ons in `config/models/billing/products.yml` and comes preconfigured with some example plans. We recommend just getting started with these plans to ensure your setup is working before customizing the attributes of these plans.
35
+
36
+ Before you can use Stripe Checkout or Stripe Billing's customer portal, these products will have to be defined on Stripe as well. You can have all locally defined products automatically created on Stripe by running the following:
37
+
38
+ ```
39
+ rake billing:stripe:populate_products_in_stripe
40
+ ```
41
+
42
+ ## 6. Import Additional Environment Variables
43
+
44
+ The script in the previous step will output some additional environment variables you need to copy into `config/application.yml`.
45
+
46
+ ## 7. Restart Rails
47
+
48
+ We've modified a bunch of environment variables, so you'll have to have to restart your Rails server before you see the results in your browser.
49
+
50
+ ```
51
+ rails restart
52
+ ```
53
+
54
+ ## 8. Test Creating a Subscription
55
+
56
+ Bullet Train comes preconfigured with a "freemium" plan, so new and existing accounts will continue to work as normal. A new "billing" menu item will appear and you can test subscription creation by clicking "upgrade" and selecting one of the two plans presented.
57
+
58
+ You should be in "test mode" on Stripe, so when prompted for a credit card number, you can enter `4242 4242 4242 4242`.
59
+
60
+ ## 9. Configuring Webhooks
61
+
62
+ Basic subscription creation will work without receiving and processing Stripe's webhooks. However, advanced payment workflows like SCA payments and customer portal cancelations and plan changes require receiving webhooks and processing them.
63
+
64
+ - Stripe can't deliver webhooks to `http://localhost:3000`, so you'll need to [get an HTTP tunnel up and running](/docs/tunneling.md). For this example, we'll assume you're using ngrok.
65
+ - Visit https://dashboard.stripe.com/test/webhooks/create.
66
+ - Configure the "endpoint URL" to be `https://your-tunnel.ngrok.io/webhooks/incoming/stripe_webhooks`, replacing `your-tunnel` with whatever the subdomain of your tunnel is.
67
+ - When configuring which events to receive, just "select all events" for simplicity. This ensures that any webhooks Bullet Train might add support for in the future will be properly handled when you upgrade.
68
+ - Add the endpoint.
69
+ - On the page for the webhook endpoint you've just configured with Stripe, click on "reveal" under the heading "signing secret". This is a secret token that is required to authenticate that webhooks your application is receiving are actually coming from Stripe. Copy this into your `config/application.yml` like so:
70
+
71
+ ```
72
+ STRIPE_WEBHOOKS_ENDPOINT_SECRET: whsec_VsM3c2zeZyqAddkaPaXzf1wJsYp2fRKR
73
+ ```
74
+
75
+ - Restart your Rails server with `rails restart`.
76
+ - Trigger a test webhook just to ensure it's resulting in an HTTP status code of 201.
77
+
78
+ ## 10. Configure Stripe Billing's Customer Portal
79
+
80
+ - Visit https://dashboard.stripe.com/test/settings/billing/portal.
81
+ - Complete all required fields.
82
+ - Be sure to add all of your actively available plans under "products".
83
+
84
+ This "products" list is what Stripe will display to users as upgrade and downgrade options in the customer portal. You shouldn't list any products here that aren't properly configured in your Rails app, otherwise the resulting webhook will fail to process. If you want to stop offering a plan, you should remove it from this list as well.
85
+
86
+ ## 11. Test Webhooks by Managing a Subscription
87
+
88
+ In the same account where you created your first test subscription, go into the "billing" menu and click "manage" on that subscription. This will take you to the Stripe Billing customer portal.
89
+
90
+ Once you're in the customer portal, you should test upgrading, downgrading, and canceling your subscription and clicking "⬅ Return to {Your Application Name}" in between each step to ensure that each change you're making is properly reflected in your Bullet Train application. This will let you know that webhooks are being properly delivered and processed and all the products in both systems are properly mapped in both directions.
data/docs/desktop.md ADDED
@@ -0,0 +1,13 @@
1
+ # Distributing as a Desktop Application
2
+
3
+ Bullet Train is fine-tuned to run well within an Electron container and the easiest way to generate code-signed, Electron-powered application bundles for Windows, macOS, and Linux is the commercial tool provided by our friends at [ToDesktop](https://www.todesktop.com).
4
+
5
+ ## Developing Desktop Experiences Locally
6
+
7
+ To test your application's desktop experience during development, you can simply [download and install Bullet Train's own prebuilt desktop application](https://dl.todesktop.com/210204wqi0hp3xe). This example application (built by ToDesktop) points to `http://localhost:3000`, so after spinning up `rails s`, you can launch this application to tweak and tune your desktop experience in real time.
8
+
9
+ This same bundle is available for the following platforms:
10
+
11
+ - [Windows](https://dl.todesktop.com/210204wqi0hp3xe/windows/nsis/x64)
12
+ - [macOS](https://dl.todesktop.com/210204wqi0hp3xe/mac/dmg/x64)
13
+ - [Linux](https://dl.todesktop.com/210204wqi0hp3xe/linux/appImage/x64)
@@ -0,0 +1,42 @@
1
+ # Examples for the `buttons` Field Partial
2
+
3
+ ## Define Available Buttons via Localization Yaml
4
+
5
+ If you invoke the field partial in `app/views/account/some_class_name/_form.html.erb` like so:
6
+
7
+ ```
8
+ <%= render 'shared/fields/buttons', form: form, method: :enabled %>
9
+ ```
10
+
11
+ You can define the available buttons in `config/locales/en/some_class_name.en.yml` like so:
12
+
13
+ ```
14
+ en:
15
+ some_class_name:
16
+ fields:
17
+ enabled:
18
+ name: &enabled Enabled
19
+ label: Should this item be enabled?
20
+ heading: Enabled?
21
+ options:
22
+ yes: "Yes, this item should be enabled."
23
+ no: "No, this item should be disabled."
24
+ ```
25
+
26
+ ## Generate Buttons Programmatically
27
+
28
+ You can generate the available buttons using a collection of database objects by passing the `options` option like so:
29
+
30
+ ```
31
+ <%= render 'shared/fields/buttons', form: form, method: :category_id,
32
+ options: Category.all.map { |category| [category.id, category.label_string] } %>
33
+ ```
34
+
35
+ ## Allow Multiple Button Selections
36
+
37
+ You can allow multiple buttons to be selected using the `multiple` option, like so:
38
+
39
+ ```
40
+ <%= render 'shared/fields/buttons', form: form, method: :category_ids,
41
+ options: Category.all.map { |category| [category.id, category.label_string] }, multiple: true %>
42
+ ```
@@ -0,0 +1,58 @@
1
+ # Examples for the `super_select` Field Partial
2
+
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](https://select2.org) library to provide you these features.
4
+
5
+ ## Define Available Buttons via Localization Yaml
6
+
7
+ If you invoke the field partial in `app/views/account/some_class_name/_form.html.erb` like so:
8
+
9
+ <pre><code><%= render 'shared/fields/super_select', form: form, method: :response_behavior %></code></pre>
10
+
11
+ You can define the available options in `config/locales/en/some_class_name.en.yml` like so:
12
+
13
+ <pre><code>en:
14
+ some_class_name:
15
+ fields:
16
+ response_behavior:
17
+ name: &response_behavior Response Behavior
18
+ label: When should this object respond to new submissions?
19
+ heading: Responds
20
+ choices:
21
+ immediate: Immediately
22
+ after_10_minutes: After a 10 minute delay
23
+ disabled: Doesn't respond
24
+ </code></pre>
25
+
26
+ ## Specify Available Choices Inline
27
+
28
+ 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
+
30
+ <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>
32
+
33
+ ## Generate Choices Programmatically
34
+
35
+ You can generate the available buttons using a collection of database objects by passing the `options` option like so:
36
+
37
+ <pre><code><%= render 'shared/fields/super_select', form: form, method: :category_id,
38
+ choices: Category.all.map { |category| [category.label_string, category.id] } %></code></pre>
39
+
40
+ ## Allowing Multiple Option Selections
41
+
42
+ Here is an example allowing multiple team members to be assigned to a (hypothetical) `Project` model:
43
+
44
+ <pre><code><%= render 'shared/fields/super_select', form: form, method: :membership_ids,
45
+ choices: @project.valid_memberships.map { |membership| [membership.name, membership.id] },
46
+ html_options: {multiple: true} %>
47
+ </code></pre>
48
+
49
+ The `html_options` key is just inherited from the underlying Rails select form field helper.
50
+
51
+ ## Allowing Search
52
+
53
+ Here is the same example, with search enabled:
54
+
55
+ <pre><code><%= render 'shared/fields/super_select', form: form, method: :membership_ids,
56
+ choices: @project.valid_memberships.map { |membership| [membership.name, membership.id] },
57
+ html_options: {multiple: true}, other_options: {search: true} %>
58
+ </code></pre>
@@ -0,0 +1,132 @@
1
+ # Field Partials
2
+ Bullet Train includes a collection of view partials that are intended to [DRY-up](https://en.wikipedia.org/wiki/Don't_repeat_yourself) as much redundant presentation logic as possible for different types of form fields without taking on a third-party dependency like Formtastic.
3
+
4
+ ## Responsibilities
5
+ These form field partials standardize and centralize the following behavior across all form fields that use them:
6
+
7
+ - Apply theme styling and classes.
8
+ - Display any error messages for a specific field inline under the field itself.
9
+ - Display a stylized asterisk next to the label of fields that are known to be required.
10
+ - Any labels, placeholder values, and help text are defined in a standardized way in the model's localization Yaml file.
11
+ - For fields presenting a static list of options (e.g. a list of buttons or a select field) the options can be defined in the localization Yaml file.
12
+
13
+ It's a simple set of responsibilities, but putting them all together in one place cleans up a lot of form view code. One of the most compelling features of this "field partials" approach is that they're just HTML in ERB templates using standard Rails form field helpers within the standard Rails `form_with` method. That means there are no "last mile" issues if you need to customize the markup being generated. There's no library to fork or classes to override.
14
+
15
+ ## The Complete Package
16
+ Each field partial can optionally include whichever of the following are required to fully support it:
17
+
18
+ - **Controller assignment helper** to be used alongside Strong Parameters to convert whatever is submitted in the form to the appropriate ActiveRecord attribute value.
19
+ - **Turbo-compatible JavaScript invocation** of any third-party library that helps support the field partial.
20
+ - **Theme-compatible styling** to ensure any third-party libraries "fit in".
21
+ - **Capybara testing helper** to ensure it's easy to inject values into a field partial in headless browser tests.
22
+
23
+ ## Basic Usage
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
+
26
+ ```
27
+ <%= form.text_field :text_field_value, autofocus: true %>
28
+ ```
29
+
30
+ Using the field partials, the same field would be implemented as follows:
31
+
32
+ ```
33
+ <%= render 'shared/fields/text_field', form: form, method: :text_field_value, options: {autofocus: true} %>
34
+ ```
35
+
36
+ At first blush it might look like a more verbose invocation, but that doesn't take into account that the first vanilla Rails example doesn't handle the field label or any other related functionality.
37
+
38
+ Breaking down the invocation:
39
+
40
+ - `text_field` matches the name of the native Rails form field helper we want to invoke.
41
+ - The `form` option passes a reference to the form object the field will exist within.
42
+ - The `method` option specifies which attribute of the model the field represents, in the same way as the first parameter of the basic Rails `text_field` helper.
43
+ - The `options` option is basically a passthrough, allowing you to specify options which will passed directly to the underlying Rails form field helper.
44
+
45
+ The 1:1 relationship between these field partials and their underlying Rails form helpers is an important design decision. For example, the way `options` is passed through to native Rails form field helpers means that experienced Rails developers will still be able to leverage what they remember about using Rails, while those of us who don't readily remember all the various options of those helpers can make use of [the standard Rails documentation](https://guides.rubyonrails.org/form_helpers.html) and the great wealth of Rails code examples available online and still take advantage of these field partials. That means the amount of documentation we need to maintain for these field partials is strictly for those features that are in addition to what Rails provides by default.
46
+
47
+ Individual field partials might have additional options available based on the underlying Rails form field helper. Links to the documentation for individual form field partials are listed at the end of this page.
48
+
49
+ ## `options` vs. `other_options`
50
+
51
+ Because Bullet Train field partials have more responsibilities than the underlying Rails form field helpers, there are also additional options for things like hiding labels, displaying specific error messages, etc. For these options, we pass them separately as `other_options`. This keeps them separate from the options in `options` that will be passed directly to the underlying Rails form field helper.
52
+
53
+ For example, to suppress a label on any field, we can use the `hide_label` option like so:
54
+
55
+ ```
56
+ <%= render 'shared/fields/text_field', form: form, method: :text_field_value, other_options: {hide_label: true} %>
57
+ ```
58
+
59
+ ### Globally-Available `other_options` Options
60
+
61
+ | Key | Value Type | Description |
62
+ | --- | --- | --- |
63
+ | `help` | string | Display a specific help string. |
64
+ | `error` | string | Display a specific error string. |
65
+ | `hide_label` | boolean | Hide the field label. |
66
+
67
+ ## Reducing Repetition
68
+ When you're including multiple fields, you can DRY up redundant settings (e.g. `form: form`) like so:
69
+
70
+ ```
71
+ <% with_field_settings form: form do %>
72
+ <%= render 'shared/fields/text_field', method: :text_field_value, options: {autofocus: true} %>
73
+ <%= render 'shared/fields/buttons', method: :button_value %>
74
+ <%= render 'shared/fields/cloudinary_image', method: :cloudinary_image_value %>
75
+ <% end %>
76
+ ```
77
+
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.
80
+
81
+ ## Yaml Configuration
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
+
84
+ <pre><code>text_field_value:
85
+ name: &text_field_value Text Field Value
86
+ label: *text_field_value
87
+ heading: *text_field_value
88
+ </code></pre>
89
+
90
+ 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
+ <pre><code>text_field_value:
93
+ name: &text_field_value Text Field Value
94
+ label: "What should the value of this text field be?"
95
+ heading: *text_field_value
96
+ </code></pre>
97
+
98
+ 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
+
100
+ <pre><code>text_field_value:
101
+ name: &text_field_value Text Field Value
102
+ label: "What should the value of this text field be?"
103
+ heading: *text_field_value
104
+ placeholder: "Type your response here"
105
+ help: "The value can be anything you want it to be!"
106
+ </code></pre>
107
+
108
+ 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
+
110
+ ## Available Field Partials
111
+
112
+ | Field Partial | Multiple Values? | Assignment Helpers | JavaScript Library | Description | Commercial License Required |
113
+ | --- | --- | --- | --- | --- | --- |
114
+ | `boolean` | | `assign_boolean` | | | |
115
+ | [`buttons`](/docs/field-partials/buttons.md) | Optionally | `assign_checkboxes` | | | |
116
+ | `cloudinary_image` | | | | | |
117
+ | `color_picker` | | | [pickr](https://simonwep.github.io/pickr/) | | |
118
+ | `date_and_time_field` | | `assign_date_and_time` | [Date Range Picker](https://www.daterangepicker.com) | | |
119
+ | `date_field` | | `assign_date` | [Date Range Picker](https://www.daterangepicker.com) | | |
120
+ | `email_field` | | | | | |
121
+ | `file_field` | | | [Active Storage](https://edgeguides.rubyonrails.org/active_storage_overview.html) | | |
122
+ | `options` | Optionally | `assign_checkboxes` | | | |
123
+ | `password_field` | | | | | |
124
+ | `phone_field` | | | [International Telephone Input](https://intl-tel-input.com) | Ensures telephone numbers are in a format that can be used by providers like Twilio. | |
125
+ | [`super_select`](/docs/field-partials/super-select.md) | Optionally | `assign_select_options` | [Select2](https://select2.org) | Provides powerful option search, AJAX search, and multi-select functionality. | |
126
+ | `text_area` | | | | | |
127
+ | `text_field` | | | | | |
128
+ | `trix_editor` | | | [Trix](https://github.com/basecamp/trix) | Basic HTML-powered formatting features and support for at-mentions amongst team members. | |
129
+
130
+ ## Additional Field Partials Documentation
131
+ - [`buttons`](/docs/field-partials/buttons.md)
132
+ - [`super_select`](/docs/field-partials/super-select.md)
@@ -0,0 +1,50 @@
1
+ # Font Awesome Pro
2
+
3
+ By default, Bullet Train ships with both [Themify Icons](https://themify.me/themify-icons) and [Font Awesome Pro's Light icons](https://fontawesome.com/icons?d=gallery&s=light) preconfigured for each menu item. However, Font Awesome Pro is a [paid product](https://fontawesome.com/plans), so by default Bullet Train falls back to showing the Themify icons.
4
+
5
+ In our experience, there is no better resource than Font Awesome Pro for finding the perfect icon for every model when you're using Super Scaffolding, so we encourage you to make the investment. Once you configure Font Awesome Pro in your environment, its icons will take precedence over the Themify Icons that were provided as a fallback.
6
+
7
+ ## Configuring Font Awesome Pro
8
+
9
+ ### 1. Set Authentication Token Environment Variable
10
+
11
+ Once you buy a license for Font Awesome Pro, set `FONTAWESOME_NPM_AUTH_TOKEN` in your shell environment to be equal to your key as presented [on their instructions page](https://fontawesome.com/how-to-use/on-the-web/setup/using-package-managers). Unfortunately, it's not enough to simply set `FONTAWESOME_NPM_AUTH_TOKEN` in `config/application.yml` like you might be thinking, because that value won't be picked up when you run `yarn install`.
12
+
13
+ #### If you're using **Bash**:
14
+ - Add `export FONTAWESOME_NPM_AUTH_TOKEN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` in `~/.bashrc`.
15
+ - Restart your terminal.
16
+
17
+ #### If you're using **zsh**:
18
+ - Add `export FONTAWESOME_NPM_AUTH_TOKEN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` in `~/.zshrc`.
19
+ - Restart your terminal.
20
+
21
+ If you're configuring this in another type of shell, please let us know what the steps are [in a new GitHub issue](http://github.com/bullet-train-co/bullet-train-tailwind-css/issues/new) and we'll add them here for others.
22
+
23
+ ### 2. Add `.npmrc` Configuration
24
+
25
+ Create a `.npmrc` file in the root of your project if you don't already have one, and add the following to it:
26
+
27
+ ```
28
+ @fortawesome:registry=https://npm.fontawesome.com/
29
+ //npm.fontawesome.com/:_authToken=${FONTAWESOME_NPM_AUTH_TOKEN}
30
+ ```
31
+
32
+ This will pull the environment variable in, but also be compatible with the way we need to supply this value when deploying to Heroku.
33
+
34
+ ### 3. Add Font Awesome Pro npm Package
35
+
36
+ Once you've got your Font Awesome Pro authentication token configured, you can run:
37
+
38
+ ```
39
+ yarn add @fortawesome/fontawesome-pro
40
+ ```
41
+
42
+ No, that's not a typo. [That's the name of their company.](https://fortawesome.com) If you receive an error at this point, be sure you restarted your terminal, and reach out for help!
43
+
44
+ ### 4. Add Font Awesome Pro to the Asset Pipeline
45
+
46
+ In `app/javascript/application.js`, below `require("@icon/themify-icons/themify-icons.css")`, add:
47
+
48
+ ```
49
+ require("@fortawesome/fontawesome-pro/css/all.css")
50
+ ```
@@ -0,0 +1,55 @@
1
+ # Getting Started
2
+
3
+ ## Starting a New Project
4
+
5
+ Whether you want to build a new application with Bullet Train or contribute to Bullet Train itself, you should start by following the instructions on [the starter repository](https://github.com/bullet-train-co/bullet_train).
6
+
7
+ ## Basic Techniques
8
+
9
+ If you're using Bullet Train for the first time, begin by learning these five important techniques:
10
+
11
+ 1. Use `rails g model` to create and `bin/super-scaffold` to scaffold a new model:
12
+
13
+ ```
14
+ $ rails g model Project team:references name:string
15
+ $ bin/super-scaffold crud Project Team name:text_field
16
+ ```
17
+
18
+ In this example, `Team` refers to the immediate parent of the `Project` resource. For more details, just run `bin/super-scaffold` or [read the documentation](https://github.com/bullet-train-co/bullet_train-base/blob/main/docs/super-scaffolding.md).
19
+
20
+ 2. Use `rails g migration` and `bin/super-scaffold` to add a new field to a model you've already scaffolded:
21
+
22
+ ```
23
+ $ rails g migration add_description_to_projects description:text
24
+ $ bin/super-scaffold crud-field Project description:trix_editor
25
+ ```
26
+
27
+ These first two points about Super Scaffolding are just the tip of the iceberg, so be sure to circle around and [read the full documentation](https://github.com/bullet-train-co/bullet_train-base/blob/main/docs/super-scaffolding.md).
28
+
29
+ 3. Figure out which ERB views are powering something you see in the UI by:
30
+
31
+ - Right clicking the element.
32
+ - Selecting "Inspect Element".
33
+ - Looking for the `<!--XRAY START ...-->` comment above the element you've selected.
34
+
35
+ 4. Figure out the full I18N translation key of any string on the page by adding `?show_locales=true` to the URL.
36
+
37
+ 5. Use `bin/resolve` to figure out where framework or theme things are coming from and eject them if you need to customize something locally:
38
+
39
+ ```
40
+ $ bin/resolve Users::Base
41
+ $ bin/resolve en.account.teams.show.header --open
42
+ $ bin/resolve shared/box --open --eject
43
+ ```
44
+
45
+ Also, for inputs that can't be provided on the shell, there's an interactive mode where you can paste them:
46
+
47
+ ```
48
+ $ bin/resolve --interactive --eject --open
49
+ ```
50
+
51
+ And then paste any input, e.g.:
52
+
53
+ ```
54
+ <!--XRAY START 73 /Users/andrewculver/.rbenv/versions/3.1.1/lib/ruby/gems/3.1.0/gems/bullet_train-themes-light-1.0.10/app/views/themes/light/commentary/_box.html.erb-->
55
+ ```
data/docs/heroku.md ADDED
@@ -0,0 +1,91 @@
1
+ # Deploying to Heroku
2
+
3
+ When you're ready to deploy to Heroku, it's highly recommended you use this button:
4
+
5
+ [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=http://github.com/bullet-train-co/bullet_train)
6
+
7
+ This button leverages the configuration found in `app.json`, including sensible defaults for dyno formation, third-party services, buildpack configuration, etc.
8
+
9
+ ## What's Included?
10
+
11
+ ### Required Add-Ons
12
+ We've included the "entry-level but production-grade" service tier across the board for:
13
+
14
+ - [Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql)
15
+ - [Heroku Redis](https://elements.heroku.com/addons/heroku-redis) to support Sidekiq and Action Cable.
16
+ - [Memcachier](https://elements.heroku.com/addons/memcachier) to support Rails Cache.
17
+ - [HDrive](https://elements.heroku.com/addons/hdrive) to support off-server file uploads backed by AWS S3.
18
+ - [Cloudinary](https://cloudinary.com) to support off-server image uploads and ImageMagick processing.
19
+ - [Heroku Scheduler](https://elements.heroku.com/addons/scheduler) for cron jobs.
20
+ - [Rails Autoscale](https://railsautoscale.com) for best-of-breed reactive performance monitoring.
21
+ - [Honeybadger](https://www.honeybadger.io) and [Sentry](https://elements.heroku.com/addons/sentry), both free, for redundant error tracking.
22
+ - [Expedited Security](https://expeditedsecurity.com)'s [Real Email](https://elements.heroku.com/addons/realemail) to reduce accounts created with fake and unreachable emails, which will subsequently hurt your email deliverability.
23
+
24
+ ## Additional Required Steps
25
+ Even after using the above button, there are a few steps that need to be performed manually using the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli):
26
+
27
+ ### 1. Add Heroku as a Remote in Your Local Repository
28
+
29
+ ```
30
+ heroku git:remote -a YOUR_HEROKU_APP_NAME
31
+ ```
32
+
33
+ After this, you'll be able to deploy updates to your app like so:
34
+
35
+ ```
36
+ git push heroku main
37
+ ````
38
+
39
+ ### 2. Running Database Migrations and Seeds
40
+ We've decided not to configure the application to automatically run database migrations after a deploy for the time being. For that reason, you'll need to run the migrations and seeds manually, like so:
41
+
42
+ ```
43
+ heroku run rake db:migrate
44
+ heroku run rake db:seed
45
+ ```
46
+
47
+ ### 3. Enabling Runtime Dyno Metadata
48
+ We include [Honeybadger](http://honeybadger.io) and Sentry (both at a free tier) for redundant error tracking by default. Sentry requires the following Heroku labs feature to be enabled:
49
+
50
+ ```
51
+ heroku labs:enable runtime-dyno-metadata
52
+ ```
53
+
54
+ ### 4. Improve Boot Time
55
+ You can cut your application boot time in half by enabling the following Heroku Labs feature. See [this blog post](https://dev.to/dbackeus/cut-your-rails-boot-times-on-heroku-in-half-with-a-single-command-514d) for more details.
56
+
57
+ ```
58
+ heroku labs:enable build-in-app-dir
59
+ ```
60
+
61
+ ### 5. Adding Your Actual Domain
62
+
63
+ The most common use case for Bullet Train applications is to be hosted at some appropriate subdomain (e.g. `app.YOURDOMAIN.COM`) while a marketing site is hosted with a completely different service at the apex domain (e.g. just `YOURDOMAIN.COM`) or `www.YOURDOMAIN.COM`. To accomplish this, do the following in your shell:
64
+
65
+ ```
66
+ heroku domains:add app.YOURDOMAIN.COM
67
+ ```
68
+
69
+ The output for this command will say something like:
70
+
71
+ ```
72
+ Configure your app's DNS provider to point to the DNS Target SOMETHING-SOMETHING-XXX.herokudns.com.
73
+ ```
74
+
75
+ On most DNS providers this means going into the DNS records for `YOURDOMAIN.COM` and adding a *CNAME* record for the `app` subdomain with a value of `SOMETHING-SOMETHING-XXX.herokudns.com` (except using the actual value provided by the Heroku CLI) and whatever TTL refresh rate you desire. I always set this as low as possible at first to make it easier to fix any mistakes I've made.
76
+
77
+ After you've added that record, you need to update the following environment settings on the Heroku app:
78
+
79
+ ```
80
+ heroku config:set BASE_URL=https://app.YOURDOMAIN.COM
81
+ heroku config:set MARKETING_SITE_URL=https://YOURDOMAIN.COM
82
+ ```
83
+
84
+ You'll also need to enable Heroku's Automated Certificate Management to have them handle provisioning and renewing your Let's Encrypt SSL certificates:
85
+
86
+ ```
87
+ heroku certs:auto:enable
88
+ heroku certs:auto
89
+ ```
90
+
91
+ You should be done now and your app should be available at `https://app.YOURDOMAIN.COM/account` and any hits to `https://app.YOURDOMAIN.COM` (e.g. when users sign out, etc.) will be redirected to your marketing site.
data/docs/i18n.md ADDED
@@ -0,0 +1,3 @@
1
+ # Translations and Internationalization
2
+
3
+ Bullet Train and views generated by Super Scaffolding are localized by default, meaning all of the human-readable text in your application has been extracted into a YAML configuration file in `config/locales/en` and can be translated into any language you would like to target.
data/docs/index.md ADDED
@@ -0,0 +1,52 @@
1
+ # Bullet Train Developer Documentation
2
+
3
+ > This release of Bullet Train is still a pre-release, so please pardon the dust while we work to complete the documentation for certain topics.
4
+
5
+ ## Introduction
6
+ - [What is Bullet Train?](https://bullettrain.co) <i class="ti ti-new-window ml-2"></i>
7
+ - [Getting Started](/docs/getting-started.md)
8
+ - [Upgrading](/docs/upgrades.md)
9
+
10
+ ## General Topics
11
+ - [Domain Modeling](/docs/modeling.md)
12
+ - [Dealing with Indirection](/docs/indirection.md)
13
+ - [Overriding the Framework](/docs/overriding.md)
14
+ - [Setting up a Tunnel](/docs/tunneling.md)
15
+
16
+ ## Developer Tools
17
+ - [Super Scaffolding](/docs/super-scaffolding.md)
18
+ - [Database Seeds](/docs/seeds.md)
19
+ - [Test Suite](/docs/testing.md)
20
+ - [Point-and-Click Test Writing](https://github.com/bullet-train-co/magic_test) <i class="ti ti-new-window ml-2"></i>
21
+
22
+ ## Accounts & Teams
23
+ - [Authentication](/docs/authentication.md)
24
+ - [Teams](/docs/teams.md)
25
+ - [Roles and Permissions](/docs/permissions.md)
26
+ - [Onboarding](/docs/onboarding.md)
27
+ - [Namespacing](/docs/namespacing.md)
28
+
29
+ ## UI
30
+ - [Field Partials](/docs/field-partials.md)
31
+ - [Theme Engine](/docs/themes.md)
32
+ - [Partial Improvements](https://github.com/bullet-train-co/nice_partials) <i class="ti ti-new-window ml-2"></i>
33
+
34
+ ## Billing
35
+ - [Stripe](/docs/billing/stripe.md)
36
+
37
+ ## Integration
38
+ - [OAuth Providers](/docs/oauth.md)
39
+ - [REST API](/docs/api.md)
40
+ - [Outgoing Webhooks](/docs/webhooks/outgoing.md)
41
+ - [Incoming Webhooks](/docs/webhooks/incoming.md)
42
+
43
+ ## Add-Ons
44
+ - [Font Awesome Pro](/docs/font-awesome-pro.md)
45
+
46
+ ## Production
47
+ - [Heroku](/docs/heroku.md)
48
+ - [Desktop Applications](/docs/desktop.md)
49
+
50
+ <hr>
51
+
52
+ Overwhelmed? [YOLO](https://github.com/bullet-train-co/bullet_train#readme).