diff --git a/Gemfile.lock b/Gemfile.lock index 09e284b0b..59c1891fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/app/assets/stylesheets/events.css b/app/assets/stylesheets/events.css index 83f4e1098..2ff88e5eb 100644 --- a/app/assets/stylesheets/events.css +++ b/app/assets/stylesheets/events.css @@ -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 /* ------------------------------------------------------------------------ */ diff --git a/app/assets/stylesheets/lexxy.css b/app/assets/stylesheets/lexxy.css index 5d0f37dc3..e3f8f8cbd 100644 --- a/app/assets/stylesheets/lexxy.css +++ b/app/assets/stylesheets/lexxy.css @@ -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; diff --git a/app/assets/stylesheets/rich-text-content.css b/app/assets/stylesheets/rich-text-content.css index 9832dbc93..72cba909b 100644 --- a/app/assets/stylesheets/rich-text-content.css +++ b/app/assets/stylesheets/rich-text-content.css @@ -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); diff --git a/app/models/account.rb b/app/models/account.rb index 6c42bcdfb..0c730a937 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -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! diff --git a/app/models/account/seedeable.rb b/app/models/account/seedeable.rb new file mode 100644 index 000000000..7e080d6ba --- /dev/null +++ b/app/models/account/seedeable.rb @@ -0,0 +1,7 @@ +module Account::Seedeable + extend ActiveSupport::Concern + + def setup_customer_template + Account::Seeder.new(self, User.active.first).seed + end +end diff --git a/app/models/account/seeder.rb b/app/models/account/seeder.rb new file mode 100644 index 000000000..80af1251a --- /dev/null +++ b/app/models/account/seeder.rb @@ -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 +

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.

+


+ + HTML + + playground.cards.create! creator: creator, title: "Grab the invite link to invite someone else", status: "published", description: <<~HTML +

Open Fizzy menu, select “+ Add people”, then copy the invite link. You can give this link to someone else so they can make an login for themselves in your account.

+ HTML + + playground.cards.create! creator: creator, title: "Head back home to check out activity", status: "published", description: <<~HTML +

Hit “1” or pull down the BOXCAR menu and select “Home”.

+ HTML + + playground.cards.create! creator: creator, title: "Check out all cards assigned to you", status: "published", description: <<~HTML +

Pull down the Fizzy menu at the top of the screen, and select “Assigned to me” or just hit “3” on your keyboard any time.

+ HTML + + playground.cards.create! creator: creator, title: "Open the Fizzy menu", status: "published", description: <<~HTML +

The Fizzy menu is how you get around the app. Click “Fizzy” at the top of the screen or hit the “J” key on your keyboard to pop it open.

+ HTML + + playground.cards.create! creator: creator, title: "Assign this card to yourself", status: "published", description: <<~HTML +

Click the little head with the + next to it, pick yourself.

+ HTML + + playground.cards.create! creator: creator, title: "Tag this card “Design” then move it to YES", status: "published", description: <<~HTML +

Click the little Tag icon, type “design”, then “Create tag”. Then, move the card to the new “YES” column you created in the previous step.

+ HTML + + playground.cards.create! creator: creator, title: "Make two more columns", status: "published", description: <<~HTML +
    +
  1. Make one called "Yes"
  2. +
  3. Make another called "Working on"
  4. +
+


+

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.

+


+

After that, drag this card to “DONE” or select “DONE” in the sidebar.

+ HTML + + playground.cards.create! creator: creator, title: "Move this card to NOT NOW", status: "published", description: <<~HTML +

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.

+ HTML + + playground.cards.create! creator: creator, title: "Rename this card", status: "published", description: <<~HTML +
    +
  1. Click the title and you can rename the card, change the description, or add more information to the card.
  2. +
  3. Then, hit "Mark as Done" at the bottom of the card.
  4. +
  5. Finally, hit “←Playground” in the top left of the screen to go back to the board.
  6. +
+ HTML + end + + def delete_everything + Current.set session: session do + Collection.destroy_all + end + end +end diff --git a/app/models/collection.rb b/app/models/collection.rb index 1bfc4be2a..ae09d9471 100644 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -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 diff --git a/app/models/concerns/attachments.rb b/app/models/concerns/attachments.rb index f4328600e..1d1c2c4d6 100644 --- a/app/models/concerns/attachments.rb +++ b/app/models/concerns/attachments.rb @@ -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 diff --git a/app/views/action_text/attachables/_remote_image.html.erb b/app/views/action_text/attachables/_remote_image.html.erb new file mode 100644 index 000000000..174a95c5e --- /dev/null +++ b/app/views/action_text/attachables/_remote_image.html.erb @@ -0,0 +1,8 @@ +
+ <%= image_tag remote_image.url, width: remote_image.width, height: remote_image.height %> + <% if caption = remote_image.try(:caption) %> +
+ <%= caption %> +
+ <% end %> +
diff --git a/app/views/action_text/attachables/_remote_video.html.erb b/app/views/action_text/attachables/_remote_video.html.erb new file mode 100644 index 000000000..5233d062a --- /dev/null +++ b/app/views/action_text/attachables/_remote_video.html.erb @@ -0,0 +1,10 @@ +
+ <%= 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) %> +
+ <%= caption %> +
+ <% end %> +
diff --git a/app/views/collections/edit/_delete.html.erb b/app/views/collections/edit/_delete.html.erb index 7f13e84b1..627bfd1bd 100644 --- a/app/views/collections/edit/_delete.html.erb +++ b/app/views/collections/edit/_delete.html.erb @@ -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" %> - Delete this board - <% 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" %> + Delete this board <% end %> <% end %> + diff --git a/app/views/events/event/_attachments.html.erb b/app/views/events/event/_attachments.html.erb index 9a255e8cb..faaf73f5a 100644 --- a/app/views/events/event/_attachments.html.erb +++ b/app/views/events/event/_attachments.html.erb @@ -1,19 +1,7 @@ -<% if eventable&.has_attachments? %> +<% if eventable&.has_attachments? || eventable&.has_remote_images? || eventable&.has_remote_videos? %> - <% 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 %> -
- <%= attachment.filename.extension&.downcase.presence || "unknown" %> -
- <% 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 %>
<% end %> diff --git a/app/views/events/event/attachments/_attachment.html.erb b/app/views/events/event/attachments/_attachment.html.erb new file mode 100644 index 000000000..c1eb254d0 --- /dev/null +++ b/app/views/events/event/attachments/_attachment.html.erb @@ -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 %> +
+ <%= attachment.filename.extension&.downcase.presence || "unknown" %> +
+<% end %> diff --git a/app/views/events/event/attachments/_remote_image.html.erb b/app/views/events/event/attachments/_remote_image.html.erb new file mode 100644 index 000000000..baec7f632 --- /dev/null +++ b/app/views/events/event/attachments/_remote_image.html.erb @@ -0,0 +1 @@ +<%= image_tag remote_image.url, class: "attachment attachment--image", width: remote_image.width, height: remote_image.height %> diff --git a/app/views/events/event/attachments/_remote_video.html.erb b/app/views/events/event/attachments/_remote_video.html.erb new file mode 100644 index 000000000..78199e296 --- /dev/null +++ b/app/views/events/event/attachments/_remote_video.html.erb @@ -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 %> diff --git a/app/views/events/index.html.erb b/app/views/events/index.html.erb index 1355ca229..ca071f189 100644 --- a/app/views/events/index.html.erb +++ b/app/views/events/index.html.erb @@ -23,13 +23,3 @@ <%= day_timeline_pagination_link(@day_timeline, @filter) %> <% end %> <% end %> - -
- -
diff --git a/app/views/my/menus/_places.html.erb b/app/views/my/menus/_places.html.erb index ee7b23de0..53802ce7d 100644 --- a/app/views/my/menus/_places.html.erb +++ b/app/views/my/menus/_places.html.erb @@ -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" %> diff --git a/db/seeds.rb b/db/seeds.rb index f70c87ccd..2d1002463 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -27,7 +27,6 @@ def create_tenant(signal_account_name) membership: membership } ) - account.setup_basic_template end ApplicationRecord.current_tenant = tenant_id diff --git a/gems/fizzy-saas/app/models/signup.rb b/gems/fizzy-saas/app/models/signup.rb index 58ee5775a..ed9b94528 100644 --- a/gems/fizzy-saas/app/models/signup.rb +++ b/gems/fizzy-saas/app/models/signup.rb @@ -116,7 +116,7 @@ class Signup } ) @user = User.find_by!(role: :admin) - @account.setup_basic_template + @account.setup_customer_template end end diff --git a/gems/fizzy-saas/test/models/signup_test.rb b/gems/fizzy-saas/test/models/signup_test.rb index 44d801017..685b25b38 100644 --- a/gems/fizzy-saas/test/models/signup_test.rb +++ b/gems/fizzy-saas/test/models/signup_test.rb @@ -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( diff --git a/lib/tasks/seed.rake b/lib/tasks/seed.rake new file mode 100644 index 000000000..71483eaf8 --- /dev/null +++ b/lib/tasks/seed.rake @@ -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 diff --git a/script/create-account.rb b/script/create-account.rb index f0cf2b16a..1a3a7cca4 100755 --- a/script/create-account.rb +++ b/script/create-account.rb @@ -68,9 +68,6 @@ Current.set( email_address: owner_email } ) - - # Setup basic template - account.setup_basic_template end puts "✓ Tenant created" diff --git a/test/models/account/seedeable_test.rb b/test/models/account/seedeable_test.rb new file mode 100644 index 000000000..aba88a2a5 --- /dev/null +++ b/test/models/account/seedeable_test.rb @@ -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