Merge pull request #1449 from basecamp/seed-new-accounts
System to seed new accounts
This commit is contained in:
+1
-1
@@ -296,7 +296,7 @@ GEM
|
||||
logger (~> 1.6)
|
||||
letter_opener (1.10.0)
|
||||
launchy (>= 2.2, < 4)
|
||||
lexxy (0.1.13.beta)
|
||||
lexxy (0.1.14.beta)
|
||||
rails (>= 8.0.2)
|
||||
lint_roller (1.1.0)
|
||||
logger (1.7.0)
|
||||
|
||||
@@ -231,17 +231,6 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.events__welcome-video {
|
||||
.events:has(.day-timeline-pagination-link) + & {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
iframe {
|
||||
aspect-ratio: 16 / 9;
|
||||
inline-size: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Event
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
@@ -163,6 +163,10 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:where(.lexxy-editor__toolbar-spacer) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Based on .input, .input--select */
|
||||
.lexxy-code-language-picker {
|
||||
-webkit-appearance: none;
|
||||
|
||||
@@ -61,6 +61,21 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
:where(hr) {
|
||||
block-size: 0;
|
||||
border-block-end: 1px solid currentColor;
|
||||
inline-size: 20%;
|
||||
margin: var(--block-margin) 0;
|
||||
}
|
||||
|
||||
.horizontal-divider {
|
||||
margin-inline: 0;
|
||||
}
|
||||
|
||||
.lexxy-content__strikethrough {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* Code */
|
||||
:where(code, pre) {
|
||||
background-color: var(--color-canvas);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Account < ApplicationRecord
|
||||
include Entropic
|
||||
include Entropic, Seedeable
|
||||
|
||||
has_many_attached :uploads
|
||||
|
||||
@@ -25,12 +25,6 @@ class Account < ApplicationRecord
|
||||
"/#{tenant}"
|
||||
end
|
||||
|
||||
def setup_basic_template
|
||||
user = User.first
|
||||
|
||||
Collection.create!(name: "Cards", creator: user, all_access: true)
|
||||
end
|
||||
|
||||
private
|
||||
def create_join_code
|
||||
Account::JoinCode.create!
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module Account::Seedeable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def setup_customer_template
|
||||
Account::Seeder.new(self, User.active.first).seed
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,93 @@
|
||||
class Account::Seeder
|
||||
attr_reader :account, :creator
|
||||
|
||||
def initialize(account, creator)
|
||||
@account = account
|
||||
@creator = creator
|
||||
end
|
||||
|
||||
def seed
|
||||
Current.set session: session do
|
||||
populate
|
||||
end
|
||||
end
|
||||
|
||||
def seed!
|
||||
raise "You can't run in production environments" unless Rails.env.local?
|
||||
|
||||
delete_everything
|
||||
seed
|
||||
end
|
||||
|
||||
private
|
||||
def session
|
||||
creator.identity.sessions.last
|
||||
end
|
||||
|
||||
def populate
|
||||
# ---------------
|
||||
# Playground Collection
|
||||
# ---------------
|
||||
playground = Collection.create! name: "Playground", creator: creator, all_access: true
|
||||
|
||||
# Cards
|
||||
playground.cards.create! creator: creator, title: "Watch this: Fizzy orientation video", status: "published", description: <<~HTML
|
||||
<p>There’s a whole lot more you can do in Fizzy. In the video below 37signals founder and CEO, Jason Fried, will walk you through the basics in just 8 minutes.</p>
|
||||
<p><br></p>
|
||||
<action-text-attachment url="https://videos.37signals.com/fizzy/assets/videos/fizzyorientation-4k.mp4" caption="Fizzy orientation" content-type="video/mp4" filename="fizzyorientation-4k.mp4"></action-text-attachment>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Grab the invite link to invite someone else", status: "published", description: <<~HTML
|
||||
<p>Open Fizzy menu, select “<b><strong>+ Add people</b></strong>”, then copy the invite link. You can give this link to someone else so they can make an login for themselves in your account.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Head back home to check out activity", status: "published", description: <<~HTML
|
||||
<p>Hit “1” or pull down the BOXCAR menu and select “Home”.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Check out all cards assigned to you", status: "published", description: <<~HTML
|
||||
<p>Pull down the Fizzy menu at the top of the screen, and select “<b><strong>Assigned to me</b></strong>” or just hit “3” on your keyboard any time.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Open the Fizzy menu", status: "published", description: <<~HTML
|
||||
<p>The Fizzy menu is how you get around the app. Click “<b><strong>Fizzy</b></strong>” at the top of the screen or hit the “J” key on your keyboard to pop it open.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Assign this card to yourself", status: "published", description: <<~HTML
|
||||
<p>Click the little head with the + next to it, pick yourself.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Tag this card “Design” then move it to YES", status: "published", description: <<~HTML
|
||||
<p>Click the little Tag icon, type “design”, then “<b><strong>Create tag</b></strong>”. Then, move the card to the new “YES” column you created in the previous step.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Make two more columns", status: "published", description: <<~HTML
|
||||
<ol>
|
||||
<li>Make one called "Yes"</li>
|
||||
<li>Make another called "Working on"</li>
|
||||
</ol>
|
||||
<p><br></p>
|
||||
<p>Go back to the Board view, click the little “+” to the right of the DONE column, name the column, pick a color, then do it again.</p>
|
||||
<p><br></p>
|
||||
<p>After that, drag this card to “DONE” or select “DONE” in the sidebar.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Move this card to NOT NOW", status: "published", description: <<~HTML
|
||||
<p>You can either select “NOT NOW” over in the sidebar, or you can go back out to the board view and drag this card into the “NOT NOW” column on the left side.</p>
|
||||
HTML
|
||||
|
||||
playground.cards.create! creator: creator, title: "Rename this card", status: "published", description: <<~HTML
|
||||
<ol>
|
||||
<li>Click the title and you can rename the card, change the description, or add more information to the card.</li>
|
||||
<li>Then, hit "Mark as Done" at the bottom of the card.</li>
|
||||
<li>Finally, hit “<b><strong>←Playground</strong></b>” in the top left of the screen to go back to the board.</li>
|
||||
</ol>
|
||||
HTML
|
||||
end
|
||||
|
||||
def delete_everything
|
||||
Current.set session: session do
|
||||
Collection.destroy_all
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -11,11 +11,4 @@ class Collection < ApplicationRecord
|
||||
|
||||
scope :alphabetically, -> { order("lower(name)") }
|
||||
scope :ordered_by_recently_accessed, -> { merge(Access.ordered_by_recently_accessed) }
|
||||
|
||||
after_destroy :ensure_default_collection
|
||||
|
||||
private
|
||||
def ensure_default_collection
|
||||
Collection.create!(name: "Cards") if Collection.none?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,6 +28,22 @@ module Attachments
|
||||
attachments.any?
|
||||
end
|
||||
|
||||
def remote_images
|
||||
@remote_images ||= rich_text_record&.body&.attachables&.grep(ActionText::Attachables::RemoteImage) || []
|
||||
end
|
||||
|
||||
def has_remote_images?
|
||||
remote_images.any?
|
||||
end
|
||||
|
||||
def remote_videos
|
||||
@remote_videos ||= rich_text_record&.body&.attachables&.grep(ActionText::Attachables::RemoteVideo) || []
|
||||
end
|
||||
|
||||
def has_remote_videos?
|
||||
remote_videos.any?
|
||||
end
|
||||
|
||||
private
|
||||
def rich_text_record
|
||||
@rich_text_record ||= begin
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<figure class="attachment attachment--preview">
|
||||
<%= image_tag remote_image.url, width: remote_image.width, height: remote_image.height %>
|
||||
<% if caption = remote_image.try(:caption) %>
|
||||
<figcaption class="attachment__caption">
|
||||
<%= caption %>
|
||||
</figcaption>
|
||||
<% end %>
|
||||
</figure>
|
||||
@@ -0,0 +1,10 @@
|
||||
<figure class="attachment attachment--preview attachment--video">
|
||||
<%= tag.video controls: true, width: remote_video.width, height: remote_video.height do %>
|
||||
<%= tag.source src: remote_video.url, type: remote_video.content_type %>
|
||||
<% end %>
|
||||
<% if caption = remote_video.try(:caption) %>
|
||||
<figcaption class="attachment__caption">
|
||||
<%= caption %>
|
||||
</figcaption>
|
||||
<% end %>
|
||||
</figure>
|
||||
@@ -1,8 +1,7 @@
|
||||
<% if Current.user.collections.many? %>
|
||||
<%= form_with model: collection, class: "txt-align-center margin-block-start-auto", method: :delete do |form| %>
|
||||
<%= form.button class: "btn txt-negative borderless txt-small", data: { turbo_confirm: "Are you sure you want to permanently delete this board?" } do %>
|
||||
<%= icon_tag "trash" %>
|
||||
<span>Delete this board</span>
|
||||
<% end %>
|
||||
<%= form_with model: collection, class: "txt-align-center margin-block-start-auto", method: :delete do |form| %>
|
||||
<%= form.button class: "btn txt-negative borderless txt-small", data: { turbo_confirm: "Are you sure you want to permanently delete this board?" } do %>
|
||||
<%= icon_tag "trash" %>
|
||||
<span>Delete this board</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
<% if eventable&.has_attachments? %>
|
||||
<% if eventable&.has_attachments? || eventable&.has_remote_images? || eventable&.has_remote_videos? %>
|
||||
<span class="event_attachments margin-block-half flex align-center gap-half">
|
||||
<% eventable.attachments.each do |attachment| %>
|
||||
<% variant = Attachments::VARIANTS[:small] %>
|
||||
<% width = attachment.metadata["width"] %>
|
||||
<% height = attachment.metadata["height"] %>
|
||||
|
||||
<% if attachment.previewable? %>
|
||||
<%= image_tag url_for(attachment.preview(variant)), class: "attachment attachment--image", width: width, height: height %>
|
||||
<% elsif attachment.variable? %>
|
||||
<%= image_tag url_for(attachment.variant(variant)), class: "attachment attachment--image", width: width, height: height %>
|
||||
<% else %>
|
||||
<div class="attachment attachment--file attachment--<%= attachment.filename.extension -%>">
|
||||
<span class="attachment__icon"><%= attachment.filename.extension&.downcase.presence || "unknown" %></span>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render partial: "events/event/attachments/attachment", collection: eventable.attachments %>
|
||||
<%= render partial: "events/event/attachments/remote_image", collection: eventable.remote_images %>
|
||||
<%= render partial: "events/event/attachments/remote_video", collection: eventable.remote_videos %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<% variant = Attachments::VARIANTS[:small] %>
|
||||
<% width = attachment.metadata["width"] %>
|
||||
<% height = attachment.metadata["height"] %>
|
||||
|
||||
<% if attachment.previewable? %>
|
||||
<%= image_tag url_for(attachment.preview(variant)), class: "attachment attachment--image", width: width, height: height %>
|
||||
<% elsif attachment.variable? %>
|
||||
<%= image_tag url_for(attachment.variant(variant)), class: "attachment attachment--image", width: width, height: height %>
|
||||
<% else %>
|
||||
<div class="attachment attachment--file attachment--<%= attachment.filename.extension -%>">
|
||||
<span class="attachment__icon"><%= attachment.filename.extension&.downcase.presence || "unknown" %></span>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -0,0 +1 @@
|
||||
<%= image_tag remote_image.url, class: "attachment attachment--image", width: remote_image.width, height: remote_image.height %>
|
||||
@@ -0,0 +1,3 @@
|
||||
<%= tag.video controls: true, class: "attachment attachment--video", width: remote_video.width, height: remote_video.height do %>
|
||||
<%= tag.source src: remote_video.url, type: remote_video.content_type %>
|
||||
<% end %>
|
||||
@@ -23,13 +23,3 @@
|
||||
<%= day_timeline_pagination_link(@day_timeline, @filter) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="events__welcome-video flex justify-center">
|
||||
<iframe
|
||||
frameborder="0"
|
||||
src="https://www.youtube.com/embed/kAgUQbD9Wc0?si=IIjKjUIk5PchL0-a"
|
||||
title="Fizzy Beta orientation"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<%= collapsible_nav_section "Jump to…" do %>
|
||||
<%= filter_place_menu_item "https://www.youtube.com/watch?v=rNKRdk7DLHM", "Fizzy beta orientation", "youtube", new_window: true %>
|
||||
<%= filter_place_menu_item account_settings_path, "Account Settings", "settings" %>
|
||||
<%= filter_place_menu_item user_path(Current.user), "My Profile", "person" %>
|
||||
<%= filter_place_menu_item notifications_path, "Notifications", "bell" %>
|
||||
|
||||
@@ -27,7 +27,6 @@ def create_tenant(signal_account_name)
|
||||
membership: membership
|
||||
}
|
||||
)
|
||||
account.setup_basic_template
|
||||
end
|
||||
|
||||
ApplicationRecord.current_tenant = tenant_id
|
||||
|
||||
@@ -116,7 +116,7 @@ class Signup
|
||||
}
|
||||
)
|
||||
@user = User.find_by!(role: :admin)
|
||||
@account.setup_basic_template
|
||||
@account.setup_customer_template
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class SignupTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "#complete" do
|
||||
Account.any_instance.expects(:setup_basic_template).once
|
||||
Account.any_instance.expects(:setup_customer_template).once
|
||||
|
||||
# First create the membership
|
||||
signup_for_membership = Signup.new(
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace :seed do
|
||||
desc "Seed customer data for a specific account (e.g: rails seed:customer ARTENANT=1234)"
|
||||
task :customer, [ :tenant_id ] => "db:tenant" do |t, args|
|
||||
raise "Please provide a tenant ID: rails seed:customer ARTENANT=1234" unless ApplicationRecord.current_tenant
|
||||
|
||||
account = Account.sole
|
||||
Account::Seeder.new(account, User.active.first).seed!
|
||||
|
||||
puts "✓ Seeded account #{account.name} (tenant: #{account.id})"
|
||||
end
|
||||
end
|
||||
@@ -68,9 +68,6 @@ Current.set(
|
||||
email_address: owner_email
|
||||
}
|
||||
)
|
||||
|
||||
# Setup basic template
|
||||
account.setup_basic_template
|
||||
end
|
||||
|
||||
puts "✓ Tenant created"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
require "test_helper"
|
||||
|
||||
class Account::SedeableTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@account = Account.sole
|
||||
end
|
||||
|
||||
test "setup_customer_template adds collections, cards, and comments" do
|
||||
assert_changes -> { Collection.count } do
|
||||
assert_changes -> { Card.count } do
|
||||
@account.setup_customer_template
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user