bullet_train 1.0.24 → 1.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae940048404ec7a968aa4b625438760513aa6e5d7b54c23acf4e98e02b8c8247
4
- data.tar.gz: c68e36983962b73e19e4a73f890e134fcc45f5b529842b153c6833cfb0479afd
3
+ metadata.gz: 032a4b18fddf1103837149d569ed33e9f5d5c99d9c93bcf989ce7df55be0db16
4
+ data.tar.gz: 65caa9cbbf2f98b4f254a8aa270ee30d8f695dc90ba6d1ba769c885d70363f60
5
5
  SHA512:
6
- metadata.gz: c7034e9fbe128558dfecc7295a013340074e226dd5cbe0a92ad723238cda09afb114e0ddfdc08d92fadda0f7c0299f21fe15bce8d10089813401d03e77354c10
7
- data.tar.gz: d1c87666fa40dac9185d7fbb6f8d5421e2753f089acdf49a1f6fe90f4e1f02cb6b8c041c706cfd3204fcf7733439b3042df4c016880846945f8b6809b8a3025a
6
+ metadata.gz: f65b2c50abcdedd2c952c265ebd3dbf606696ef8ae10ab6c1cd55048a32d966182840342e7367c411ec1c3eecedef4d8a61947f094c1865040d492d1ccc09b96
7
+ data.tar.gz: f2bbf19d62e8e57ef6de9a46ddec60f9e8467c52fc0bb2d6a48dff9f046e848b91e3580cc0809c483e7c7b76b85b0e10b40f6666c19d813c0c849e4a2ea7486d
@@ -0,0 +1,8 @@
1
+ module DocumentationSupport
2
+ extend ActiveSupport::Concern
3
+
4
+ def docs
5
+ @file = params[:page].presence || "index"
6
+ render :docs, layout: "docs"
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module InviteOnlySupport
2
+ extend ActiveSupport::Concern
3
+
4
+ def invitation
5
+ return not_found unless invitation_only?
6
+ return not_found unless params[:key].present?
7
+ return not_found unless invitation_keys.include?(params[:key])
8
+ session[:invitation_key] = params[:key]
9
+ if user_signed_in?
10
+ redirect_to new_account_team_path
11
+ else
12
+ redirect_to new_user_registration_path
13
+ end
14
+ end
15
+
16
+ def not_found
17
+ render file: "#{Rails.root}/public/404.html", layout: false, status: :not_found
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module RootRedirect
2
+ extend ActiveSupport::Concern
3
+
4
+ def index
5
+ if ENV["MARKETING_SITE_URL"]
6
+ redirect_to ENV["MARKETING_SITE_URL"]
7
+ else
8
+ redirect_to new_user_session_path
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module BaseHelper
2
+ # TODO This is for the billing package to override, but I feel like there has got to be a better way to do this.
3
+ def hide_team_resource_menus?
4
+ false
5
+ end
6
+ end
@@ -0,0 +1,305 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <%
6
+ # we're going to use the
7
+ body = Nokogiri::HTML(@body)
8
+ title = body.css('h1').first.text.presence || t('application.tagline')
9
+ first_paragraph = body.css('p').first
10
+ preceding_heading = first_paragraph&.xpath("preceding-sibling::h2")
11
+ description = [preceding_heading&.text, first_paragraph&.text].select(&:present?).join(" — ") || t('application.description')
12
+ image_url = "https://avatars.githubusercontent.com/u/5976880?s=280&amp;v=4"
13
+ site_name = "Bullet Train Developer Documentation"
14
+ %>
15
+
16
+ <% content_for :title do %>
17
+ <title><%= [site_name, title, t('application.tagline')].select(&:present?).uniq.first(2).reverse.join(' — ') %></title>
18
+ <% end %>
19
+
20
+ <%= render 'themes/light/layouts/head' %>
21
+ <meta content="<%= t('application.keywords') %>" name="keywords" />
22
+ <meta content="<%= description.truncate(200) %>" name="description" />
23
+ <meta name="twitter:image:src" content="<%= image_url %>" />
24
+ <meta name="twitter:site" content="@bullettrainco" />
25
+ <meta name="twitter:card" content="summary" />
26
+ <meta name="twitter:title" content="<%= title.truncate(70) %>" />
27
+ <meta name="twitter:description" content="<%= description.truncate(160) %>" />
28
+ <meta property="og:image" content="<%= image_url %>" />
29
+ <meta property="og:site_name" content="<%= site_name %>" />
30
+ <meta property="og:type" content="object" />
31
+ <meta property="og:title" content="<%= title.truncate(95) %>" />
32
+ <meta property="og:url" content="<%= request.base_url + request.path %>" />
33
+ <meta property="og:description" content="<%= description.truncate(200) %>" />
34
+ </head>
35
+ <body class="bg-light-blue-gradient text-gray-700 text-sm font-normal dark:bg-dark-blue-gradient dark:text-sealBlue-900">
36
+ <div class="md:p-5">
37
+ <div class="h-screen md:h-auto overflow-hidden md:rounded-lg flex shadow"
38
+ data-controller="mobile-menu"
39
+ data-mobile-menu-hidden-class="hidden"
40
+ data-mobile-menu-show-event-name-value="mobile-menu:show"
41
+ data-mobile-menu-hide-event-name-value="mobile-menu:hide"
42
+ >
43
+
44
+ <% menu = capture do %>
45
+ <div class="flex items-center flex-shrink-0 p-4 bg-blue-darker md:rounded-tl-lg">
46
+ <%= image_tag image_path("light/logo/logo.png"), class: 'h-5 w-auto mx-auto' %>
47
+
48
+ <div class="lg:hidden absolute right-0">
49
+ <button class="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
50
+ data-action="reveal#hide"
51
+ >
52
+ <span class="sr-only">Close Application Menu</span>
53
+ <svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
54
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
55
+ </svg>
56
+ </button>
57
+ </div>
58
+ </div>
59
+
60
+ <nav class="flex-1 space-y-1 overflow-y-auto">
61
+ <div class="px-5 py-4" id="menu">
62
+
63
+ <%= render 'account/shared/menu/section', title: 'Introduction' do %>
64
+ <%= render 'account/shared/menu/item', url: '/docs', label: 'Table of Contents' do |p| %>
65
+ <% p.content_for :icon do %>
66
+ <i class="fal fa-home-lg-alt ti ti-list"></i>
67
+ <% end %>
68
+ <% end %>
69
+
70
+ <%= render 'account/shared/menu/item', url: '/docs/getting-started', label: 'Getting Started' do |p| %>
71
+ <% p.content_for :icon do %>
72
+ <i class="fal fa-terminal ti ti-flag"></i>
73
+ <% end %>
74
+ <% end %>
75
+
76
+ <%= render 'account/shared/menu/item', url: '/docs/philosophy', label: 'Philosophy' do |p| %>
77
+ <% p.content_for :icon do %>
78
+ <i class="fal fa-lightbulb-on ti ti-light-bulb"></i>
79
+ <% end %>
80
+ <% end %>
81
+
82
+ <%= render 'account/shared/menu/item', url: '/docs/upgrades', label: 'Upgrades' do |p| %>
83
+ <% p.content_for :icon do %>
84
+ <i class="fal fa-sparkles ti ti-arrow-up"></i>
85
+ <% end %>
86
+ <% end %>
87
+
88
+ <%= render 'account/shared/menu/item', url: '/docs/tunneling', label: 'Tunneling' do |p| %>
89
+ <% p.content_for :icon do %>
90
+ <i class="fal fa-bolt ti ti-bolt"></i>
91
+ <% end %>
92
+ <% end %>
93
+ <% end %>
94
+
95
+ <%= render 'account/shared/menu/section', title: 'Developer Tools' do %>
96
+ <%= render 'account/shared/menu/item', url: '/docs/super-scaffolding', label: 'Super Scaffolding' do |p| %>
97
+ <% p.content_for :icon do %>
98
+ <i class="fal fa-magic ti ti-wand"></i>
99
+ <% end %>
100
+ <% end %>
101
+
102
+ <%= render 'account/shared/menu/item', url: '/docs/field-partials', label: 'Field Partials' do |p| %>
103
+ <% p.content_for :icon do %>
104
+ <i class="fal fa-i-cursor ti ti-text"></i>
105
+ <% end %>
106
+ <% end %>
107
+
108
+ <%= render 'account/shared/menu/item', url: '/docs/themes', label: 'Themes' do |p| %>
109
+ <% p.content_for :icon do %>
110
+ <i class="fal fa-swatchbook ti ti-palette"></i>
111
+ <% end %>
112
+ <% end %>
113
+
114
+ <%= render 'account/shared/menu/item', url: '/docs/seeds', label: 'Database Seeds' do |p| %>
115
+ <% p.content_for :icon do %>
116
+ <i class="fal fa-seedling ti ti-server"></i>
117
+ <% end %>
118
+ <% end %>
119
+
120
+ <%= render 'account/shared/menu/item', url: '/docs/testing', label: 'Test Suite' do |p| %>
121
+ <% p.content_for :icon do %>
122
+ <i class="fal fa-check ti ti-check"></i>
123
+ <% end %>
124
+ <% end %>
125
+ <% end %>
126
+
127
+ <%= render 'account/shared/menu/section', title: 'Accounts & Teams' do %>
128
+ <%= render 'account/shared/menu/item', url: '/docs/authentication', label: 'Authentication' do |p| %>
129
+ <% p.content_for :icon do %>
130
+ <i class="fal fa-fingerprint ti ti-id-badge"></i>
131
+ <% end %>
132
+ <% end %>
133
+
134
+ <%= render 'account/shared/menu/item', url: '/docs/teams', label: 'Teams' do |p| %>
135
+ <% p.content_for :icon do %>
136
+ <i class="fal fa-users ti ti-user"></i>
137
+ <% end %>
138
+ <% end %>
139
+
140
+ <%= render 'account/shared/menu/item', url: '/docs/permissions', label: 'Roles & Permissions' do |p| %>
141
+ <% p.content_for :icon do %>
142
+ <i class="fal fa-lock-alt ti ti-lock"></i>
143
+ <% end %>
144
+ <% end %>
145
+
146
+ <%= render 'account/shared/menu/item', url: '/docs/onboarding', label: 'Onboarding' do |p| %>
147
+ <% p.content_for :icon do %>
148
+ <i class="fal fa-snowboarding ti ti-direction"></i>
149
+ <% end %>
150
+ <% end %>
151
+
152
+ <%= render 'account/shared/menu/item', url: '/docs/namespacing', label: 'Namespacing' do |p| %>
153
+ <% p.content_for :icon do %>
154
+ <i class="fal fa-object-group ti ti-widgetized"></i>
155
+ <% end %>
156
+ <% end %>
157
+ <% end %>
158
+
159
+ <%= render 'account/shared/menu/section', title: 'Billing' do %>
160
+ <%= render 'account/shared/menu/item', url: '/docs/billing/stripe', label: 'Stripe' do |p| %>
161
+ <% p.content_for :icon do %>
162
+ <i class="fab fa-stripe-s ti ti-money"></i>
163
+ <% end %>
164
+ <% end %>
165
+ <% end %>
166
+
167
+ <%= render 'account/shared/menu/section', title: 'Integration' do %>
168
+ <%= render 'account/shared/menu/item', url: '/docs/oauth', label: 'OAuth Providers' do |p| %>
169
+ <% p.content_for :icon do %>
170
+ <i class="fal fa-at ti ti-reload"></i>
171
+ <% end %>
172
+ <% end %>
173
+
174
+ <%= render 'account/shared/menu/item', url: '/docs/api', label: 'REST API' do |p| %>
175
+ <% p.content_for :icon do %>
176
+ <i class="fal fa-brackets-curly ti ti-settings"></i>
177
+ <% end %>
178
+ <% end if false %>
179
+
180
+ <%= render 'account/shared/menu/item', url: '/docs/webhooks/outgoing', label: 'Outgoing Webhooks' do |p| %>
181
+ <% p.content_for :icon do %>
182
+ <i class="fal fa-outlet ti ti-pulse"></i>
183
+ <% end %>
184
+ <% end if false %>
185
+
186
+ <%= render 'account/shared/menu/item', url: '/docs/webhooks/incoming', label: 'Incoming Webhooks' do |p| %>
187
+ <% p.content_for :icon do %>
188
+ <i class="fal fa-plug ti ti-plug"></i>
189
+ <% end %>
190
+ <% end if false %>
191
+ <% end %>
192
+
193
+ <%= render 'account/shared/menu/section', title: 'Internationalization' do %>
194
+ <%= render 'account/shared/menu/item', url: '/docs/i18n', label: 'Translations' do |p| %>
195
+ <% p.content_for :icon do %>
196
+ <i class="fal fa-language ti ti-world"></i>
197
+ <% end %>
198
+ <% end %>
199
+ <% end if false %>
200
+
201
+ <%= render 'account/shared/menu/section', title: 'Add-Ons' do %>
202
+ <%= render 'account/shared/menu/item', url: '/docs/font-awesome-pro', label: 'Font Awesome Pro' do |p| %>
203
+ <% p.content_for :icon do %>
204
+ <i class="fal fa-flag ti ti-flag"></i>
205
+ <% end %>
206
+ <% end %>
207
+ <% end %>
208
+
209
+ <%= render 'account/shared/menu/section', title: 'Deployment' do %>
210
+ <%= render 'account/shared/menu/item', url: '/docs/heroku', label: 'Heroku' do |p| %>
211
+ <% p.content_for :icon do %>
212
+ <i class="fal fa-cloud ti ti-cloud-up"></i>
213
+ <% end %>
214
+ <% end %>
215
+
216
+ <%= render 'account/shared/menu/item', url: '/docs/desktop', label: 'Desktop Applications' do |p| %>
217
+ <% p.content_for :icon do %>
218
+ <i class="fal fa-window-restore ti ti-desktop"></i>
219
+ <% end %>
220
+ <% end %>
221
+ <% end %>
222
+ </div>
223
+ </nav>
224
+ <% end %>
225
+
226
+ <div class="lg:hidden hidden"
227
+ data-mobile-menu-target="wrapper"
228
+
229
+ data-controller="reveal"
230
+ data-reveal-away-value="true"
231
+ data-reveal-hide-keys-value="escape"
232
+
233
+ data-action="mobile-menu:show->reveal#show mobile-menu:hide->reveal#hide mobile-menu-toggle->reveal#toggle reveal:hidden->mobile-menu#hideWrapper"
234
+ >
235
+ <div class="fixed inset-0 flex z-40">
236
+ <button
237
+ data-action="reveal#hide"
238
+
239
+ hidden
240
+ data-reveal
241
+ data-transition
242
+ data-transition-enter="transition-opacity ease-linear duration-200"
243
+ data-transition-enter-start="opacity-0"
244
+ data-transition-enter-end="opacity-100"
245
+ data-transition-leave="transition-opacity ease-linear duration-200"
246
+ data-transition-leave-start="opacity-100"
247
+ data-transition-leave-end="opacity-0"
248
+
249
+ class="fixed inset-0" aria-hidden="true"
250
+ >
251
+ <div class="absolute inset-0 bg-light-blue-gradient opacity-75"></div>
252
+ </button>
253
+ <div
254
+ hidden
255
+ data-reveal
256
+ data-transition
257
+ data-transition-enter="transition ease-in-out duration-200 transform"
258
+ data-transition-enter-start="-translate-x-full"
259
+ data-transition-enter-end="translate-x-0"
260
+ data-transition-leave="transition ease-in-out duration-200 transform"
261
+ data-transition-leave-start="translate-x-0"
262
+ data-transition-leave-end="-translate-x-full"
263
+
264
+ class="relative flex-1 flex flex-col max-w-xs w-full shadow-xl bg-gradient-to-b from-vividBlue-700 to-vividBlue-800 dark:from-sealBlue-200 dark:to-sealBlue-200"
265
+ >
266
+ <%= menu %>
267
+ </div>
268
+ <div class="flex-shrink-0 w-14" aria-hidden="true"></div>
269
+ </div>
270
+ </div>
271
+
272
+ <div class="hidden lg:flex lg:flex-shrink-0 bg-gradient-to-b from-vividBlue-700 to-vividBlue-800 dark:from-sealBlue-200 dark:to-sealBlue-200">
273
+ <div class="w-64">
274
+ <%= menu %>
275
+ </div>
276
+ </div>
277
+
278
+ <div class="flex flex-col w-0 flex-1 overflow-hidden bg-gray-100 dark:bg-sealBlue-200 lg:border-l dark:border-gray-500">
279
+ <main class="flex-1 relative z-0 overflow-y-auto focus:outline-none" tabindex="0">
280
+
281
+ <button class="lg:hidden h-12 w-12 ml-1 flex-none inline-flex items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue"
282
+ data-action="mobile-menu#toggle"
283
+ >
284
+ <span class="sr-only">Open Application Menu</span>
285
+ <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
286
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
287
+ </svg>
288
+ </button>
289
+
290
+ <div class="py-2 px-1">
291
+ <div class="mx-auto sm:px-6 sm:py-4 px-2">
292
+ <div class="bg-white rounded-md shadow sm:py-14 sm:px-12 py-10 px-7">
293
+ <div class="prose" style="max-width: none;">
294
+ <%= yield %>
295
+ </div>
296
+ </div>
297
+
298
+ </div>
299
+ </div>
300
+ </main>
301
+ </div>
302
+ </div>
303
+ </div>
304
+ </body>
305
+ </html>
@@ -0,0 +1,65 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+ <title>Welcome to <%= t('application.name') %>!</title>
7
+ </head>
8
+ <body>
9
+ <% if content_for? :preheader %>
10
+ <span class="preheader"><% yield :preheader %></span>
11
+ <% end %>
12
+ <table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0">
13
+ <tr>
14
+ <td align="center">
15
+ <table class="email-content" width="100%" cellpadding="0" cellspacing="0">
16
+ <tr>
17
+ <td class="email-masthead">
18
+ <a href="<%= root_url %>" class="email-masthead_name">
19
+ <%= email_image_tag("light/logo/logo.png", width: image_width_for_height('light/logo/logo.png', 50), height: 50, style: "width: #{image_width_for_height('light/logo/logo.png', 50)}px; height: 50px;") %>
20
+ </a>
21
+ </td>
22
+ </tr>
23
+ <!-- Email Body -->
24
+ <tr>
25
+ <td class="email-body" width="100%" cellpadding="0" cellspacing="0">
26
+ <table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0">
27
+ <!-- Body content -->
28
+ <tr>
29
+ <td class="content-cell">
30
+
31
+ <%= yield %>
32
+
33
+ <% if false %>
34
+ <!-- Sub copy -->
35
+ <table class="body-sub">
36
+ <tr>
37
+ <td>
38
+ <p class="sub"><%= t('.trouble') %></p>
39
+ <p class="sub">{{action_url}}</p>
40
+ </td>
41
+ </tr>
42
+ </table>
43
+ <% end %>
44
+ </td>
45
+ </tr>
46
+ </table>
47
+ </td>
48
+ </tr>
49
+ <tr>
50
+ <td>
51
+ <table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0">
52
+ <tr>
53
+ <td class="content-cell" align="center">
54
+ <p class="sub align-center">&copy; <%= t('.all_rights_reserved', year: Date.today.year, product_name: t('application.name')) %></p>
55
+ </td>
56
+ </tr>
57
+ </table>
58
+ </td>
59
+ </tr>
60
+ </table>
61
+ </td>
62
+ </tr>
63
+ </table>
64
+ </body>
65
+ </html>
@@ -0,0 +1 @@
1
+ <%= @body = markdown(File.read(Rails.root.to_s + "/docs/#{@file}.md").gsub('.md)', ')')) %>
@@ -0,0 +1,29 @@
1
+ <% content_for :preheader do %>
2
+ <%= t('.preview', @values) %>
3
+ <% end %>
4
+
5
+ <h1><%= t('.heading', @values) %></h1>
6
+ <%= t('.body.html', @values) %>
7
+
8
+ <!-- Action -->
9
+ <table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0">
10
+ <tr>
11
+ <td align="center">
12
+ <!-- Border based button https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design -->
13
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
14
+ <tr>
15
+ <td align="center">
16
+ <table border="0" cellspacing="0" cellpadding="0">
17
+ <tr>
18
+ <td>
19
+ <a href="<%= @cta_url %>" class="button button--" target="_blank"><%= t('.cta.label', @values) %></a>
20
+ </td>
21
+ </tr>
22
+ </table>
23
+ </td>
24
+ </tr>
25
+ </table>
26
+ </td>
27
+ </tr>
28
+ </table>
29
+ <%= t('.signature.html', @values.merge({support_email: t('application.support_email')})) %>
@@ -0,0 +1,31 @@
1
+ <% content_for :preheader do %>
2
+ <%= t('.preview', @values) %>
3
+ <% end %>
4
+
5
+ <h1><%= t('.heading', @values) %></h1>
6
+ <%= t('.body.html', @values) %>
7
+
8
+ <h2><%= t('.cta.heading', @values) %></h2>
9
+ <p><%= t('.cta.body', @values) %></p>
10
+ <!-- Action -->
11
+ <table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0">
12
+ <tr>
13
+ <td align="center">
14
+ <!-- Border based button https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design -->
15
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
16
+ <tr>
17
+ <td align="center">
18
+ <table border="0" cellspacing="0" cellpadding="0">
19
+ <tr>
20
+ <td>
21
+ <a href="<%= @cta_url %>" class="button button--" target="_blank"><%= t('.cta.label', @values) %></a>
22
+ </td>
23
+ </tr>
24
+ </table>
25
+ </td>
26
+ </tr>
27
+ </table>
28
+ </td>
29
+ </tr>
30
+ </table>
31
+ <%= t('.signature.html', @values.merge({support_email: t('application.support_email')})) %>
data/config/routes.rb CHANGED
@@ -1,6 +1,19 @@
1
1
  Rails.application.routes.draw do
2
+ scope module: "public" do
3
+ root to: "home#index"
4
+ get "invitation" => "home#invitation", :as => "invitation"
5
+
6
+ if Rails.env.production? ? ENV["ENABLE_DOCS"].present? : true
7
+ get "docs", to: "home#docs"
8
+ get "docs/*page", to: "home#docs"
9
+ end
10
+ end
11
+
2
12
  namespace :account do
3
13
  shallow do
14
+ # TODO we need to either implement a dashboard or deprecate this.
15
+ root to: "dashboard#index", as: "dashboard"
16
+
4
17
  resource :two_factor, only: [:create, :destroy]
5
18
 
6
19
  # user-level onboarding tasks.
@@ -1,3 +1,3 @@
1
1
  module BulletTrain
2
- VERSION = "1.0.24"
2
+ VERSION = "1.0.27"
3
3
  end
data/lib/bullet_train.rb CHANGED
@@ -7,6 +7,9 @@ require "bullet_train/super_load_and_authorize_resource"
7
7
  require "bullet_train/has_uuid"
8
8
  require "bullet_train/scope_validator"
9
9
 
10
+ require "colorizer"
11
+ require "string/emoji"
12
+
10
13
  require "devise"
11
14
  # require "devise-two-factor"
12
15
  # require "rqrcode"
@@ -32,3 +35,86 @@ module BulletTrain
32
35
  mattr_accessor :routing_concerns, default: []
33
36
  mattr_accessor :linked_gems, default: ["bullet_train"]
34
37
  end
38
+
39
+ def default_url_options_from_base_url
40
+ unless ENV["BASE_URL"].present?
41
+ if Rails.env.development?
42
+ ENV["BASE_URL"] ||= "http://localhost:3000"
43
+ else
44
+ raise "you need to define the value of ENV['BASE_URL'] in your environment. if you're on heroku, you can do this with `heroku config:add BASE_URL=https://your-app-name.herokuapp.com` (or whatever your configured domain is)."
45
+ end
46
+ end
47
+
48
+ parsed_base_url = URI.parse(ENV["BASE_URL"])
49
+ default_url_options = [:user, :password, :host, :port].map { |key| [key, parsed_base_url.send(key)] }.to_h
50
+
51
+ # the name of this property doesn't match up.
52
+ default_url_options[:protocol] = parsed_base_url.scheme
53
+
54
+ default_url_options.compact
55
+ end
56
+
57
+ def inbound_email_enabled?
58
+ ENV["INBOUND_EMAIL_DOMAIN"].present?
59
+ end
60
+
61
+ def subscriptions_enabled?
62
+ false
63
+ end
64
+
65
+ def free_trial?
66
+ ENV["STRIPE_FREE_TRIAL_LENGTH"].present?
67
+ end
68
+
69
+ def stripe_enabled?
70
+ ENV["STRIPE_CLIENT_ID"].present?
71
+ end
72
+
73
+ # 🚅 super scaffolding will insert new oauth providers above this line.
74
+
75
+ def webhooks_enabled?
76
+ true
77
+ end
78
+
79
+ def scaffolding_things_disabled?
80
+ ENV["HIDE_THINGS"].present? || ENV["HIDE_EXAMPLES"].present?
81
+ end
82
+
83
+ def sample_role_disabled?
84
+ ENV["HIDE_EXAMPLES"].present?
85
+ end
86
+
87
+ def demo?
88
+ ENV["DEMO"].present?
89
+ end
90
+
91
+ def cloudinary_enabled?
92
+ ENV["CLOUDINARY_URL"].present?
93
+ end
94
+
95
+ def two_factor_authentication_enabled?
96
+ ENV["TWO_FACTOR_ENCRYPTION_KEY"].present?
97
+ end
98
+
99
+ def any_oauth_enabled?
100
+ [
101
+ stripe_enabled?,
102
+ # 🚅 super scaffolding will insert new oauth provider checks above this line.
103
+ ].select(&:present?).any?
104
+ end
105
+
106
+ def invitation_only?
107
+ ENV["INVITATION_KEYS"].present?
108
+ end
109
+
110
+ def invitation_keys
111
+ ENV["INVITATION_KEYS"].split(",").map(&:strip)
112
+ end
113
+
114
+ def font_awesome?
115
+ ENV["FONTAWESOME_NPM_AUTH_TOKEN"].present?
116
+ end
117
+
118
+ def multiple_locales?
119
+ @multiple_locales ||= I18n.available_locales.many?
120
+ end
data/lib/colorizer.rb ADDED
@@ -0,0 +1,67 @@
1
+ # https://makandracards.com/makandra/24449-hash-any-ruby-object-into-an-rgb-color
2
+ module Colorizer
3
+ extend self
4
+
5
+ def colorize(object)
6
+ # Inspired by Jeremy Ruten (http://stackoverflow.com/questions/1698318/ruby-generate-a-random-hex-color)
7
+ hash = object.hash # hash an object, returns a Fixnum
8
+ trimmed_hash = hash & 0xffffff # trim the hash to the size of 6 hex digits (& is bit-wise AND)
9
+ hex_code = "%06x" % trimmed_hash # format as at least 6 hex digits, pad with zeros
10
+ "##{hex_code}"
11
+ end
12
+
13
+ def colorize_similarly(object, saturation, lightness)
14
+ rnd = ((object.hash * 7) % 100) * 0.01
15
+ hsl_to_rgb(rnd, saturation, lightness)
16
+ end
17
+
18
+ private
19
+
20
+ def hsl_to_rgb(h, sl, l)
21
+ r = l
22
+ g = l
23
+ b = l
24
+ v = l <= 0.5 ? (l * (1.0 + sl)) : (l + sl - l * sl)
25
+ if v > 0
26
+ m = l + l - v
27
+ sv = (v - m) / v
28
+ h *= 6.0
29
+ sextant = h.floor
30
+ fract = h - sextant
31
+ vsf = v * sv * fract
32
+ mid1 = m + vsf
33
+ mid2 = v - vsf
34
+ case sextant
35
+ when 0
36
+ r = v
37
+ g = mid1
38
+ b = m
39
+ when 1
40
+ r = mid2
41
+ g = v
42
+ b = m
43
+ when 2
44
+ r = m
45
+ g = v
46
+ b = mid1
47
+ when 3
48
+ r = m
49
+ g = mid2
50
+ b = v
51
+ when 4
52
+ r = mid1
53
+ g = m
54
+ b = v
55
+ when 5
56
+ r = v
57
+ g = m
58
+ b = mid2
59
+ end
60
+ end
61
+ "##{hex_color_component(r)}#{hex_color_component(g)}#{hex_color_component(b)}"
62
+ end
63
+
64
+ def hex_color_component(i)
65
+ (i * 255).floor.to_s(16).rjust(2, "0")
66
+ end
67
+ end
@@ -0,0 +1,10 @@
1
+ class String
2
+ def strip_emojis
3
+ gsub(Unicode::Emoji::REGEX, "")
4
+ end
5
+
6
+ def only_emoji?
7
+ return false if strip.empty?
8
+ strip_emojis.strip.empty?
9
+ end
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.24
4
+ version: 1.0.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
@@ -373,7 +373,10 @@ files:
373
373
  - app/controllers/concerns/account/users/controller_base.rb
374
374
  - app/controllers/concerns/controllers/base.rb
375
375
  - app/controllers/concerns/devise_current_attributes.rb
376
+ - app/controllers/concerns/documentation_support.rb
377
+ - app/controllers/concerns/invite_only_support.rb
376
378
  - app/controllers/concerns/registrations/controller_base.rb
379
+ - app/controllers/concerns/root_redirect.rb
377
380
  - app/controllers/concerns/sessions/controller_base.rb
378
381
  - app/controllers/registrations_controller.rb
379
382
  - app/controllers/sessions_controller.rb
@@ -388,6 +391,7 @@ files:
388
391
  - app/helpers/account/teams_helper.rb
389
392
  - app/helpers/account/users_helper.rb
390
393
  - app/helpers/attributes_helper.rb
394
+ - app/helpers/base_helper.rb
391
395
  - app/helpers/email_helper.rb
392
396
  - app/helpers/images_helper.rb
393
397
  - app/helpers/invitation_only_helper.rb
@@ -462,6 +466,11 @@ files:
462
466
  - app/views/devise/unlocks/new.html.erb
463
467
  - app/views/layouts/account.html.erb
464
468
  - app/views/layouts/devise.html.erb
469
+ - app/views/layouts/docs.html.erb
470
+ - app/views/layouts/mailer.html.erb
471
+ - app/views/public/home/docs.html.erb
472
+ - app/views/user_mailer/invited.html.erb
473
+ - app/views/user_mailer/welcome.html.erb
465
474
  - config/locales/en/devise.en.yml
466
475
  - config/locales/en/invitations.en.yml
467
476
  - config/locales/en/memberships.en.yml
@@ -508,6 +517,8 @@ files:
508
517
  - lib/bullet_train.rb
509
518
  - lib/bullet_train/engine.rb
510
519
  - lib/bullet_train/version.rb
520
+ - lib/colorizer.rb
521
+ - lib/string/emoji.rb
511
522
  - lib/tasks/bullet_train_tasks.rake
512
523
  homepage: https://github.com/bullet-train-co/bullet_train
513
524
  licenses: